Gibt es in Python einen Unterschied zwischen Aufrufen clear()und Zuweisen {}zu einem Wörterbuch? Wenn ja, was ist das? Beispiel:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Gibt es in Python einen Unterschied zwischen Aufrufen clear()und Zuweisen {}zu einem Wörterbuch? Wenn ja, was ist das? Beispiel:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Antworten:
Wenn Sie eine andere Variable haben, die sich ebenfalls auf dasselbe Wörterbuch bezieht, gibt es einen großen Unterschied:
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
Dies liegt daran, dass beim Zuweisen d = {}ein neues, leeres Wörterbuch erstellt und der dVariablen zugewiesen wird. Dadurch wird d2auf das alte Wörterbuch verwiesen, in dem sich noch Elemente befinden. Jedoch d.clear()löscht das gleiche Wörterbuch , dass dund d2beiden Punkte , an.
Zusätzlich zu den in anderen Antworten erwähnten Unterschieden gibt es auch einen Geschwindigkeitsunterschied. d = {} ist doppelt so schnell vorbei:
python -m timeit -s "d = {}" "for i in xrange(500000): d.clear()"
10 loops, best of 3: 127 msec per loop
python -m timeit -s "d = {}" "for i in xrange(500000): d = {}"
10 loops, best of 3: 53.6 msec per loop
d = {}sollte die Einstellung schneller sein, da die Bereinigung des Ganzen für später dem Garbage Collector überlassen werden kann.
Zusätzlich zu @odanos Antwort scheint die Verwendung d.clear()schneller zu sein, wenn Sie das Diktat mehrmals löschen möchten.
import timeit
p1 = '''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d = {}
for i in xrange(1000):
d[i] = i * i
'''
p2 = '''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d.clear()
for i in xrange(1000):
d[i] = i * i
'''
print timeit.timeit(p1, number=1000)
print timeit.timeit(p2, number=1000)
Das Ergebnis ist:
20.0367929935
19.6444659233
Mutationsmethoden sind immer dann nützlich, wenn das ursprüngliche Objekt nicht im Gültigkeitsbereich liegt:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
Durch erneutes Zuweisen des Wörterbuchs wird ein neues Objekt erstellt und das ursprüngliche Objekt nicht geändert.
Eine Sache, die nicht erwähnt wird, ist das Scoping von Problemen. Kein gutes Beispiel, aber hier ist der Fall, in dem ich auf das Problem gestoßen bin:
def conf_decorator(dec):
"""Enables behavior like this:
@threaded
def f(): ...
or
@threaded(thread=KThread)
def f(): ...
(assuming threaded is wrapped with this function.)
Sends any accumulated kwargs to threaded.
"""
c_kwargs = {}
@wraps(dec)
def wrapped(f=None, **kwargs):
if f:
r = dec(f, **c_kwargs)
c_kwargs = {}
return r
else:
c_kwargs.update(kwargs) #<- UnboundLocalError: local variable 'c_kwargs' referenced before assignment
return wrapped
return wrapped
Die Lösung ist zu ersetzen c_kwargs = {}mitc_kwargs.clear()
Wenn sich jemand ein praktischeres Beispiel ausdenkt, können Sie diesen Beitrag bearbeiten.
global c_kwargswürde wohl auch nein funktionieren? Obwohl es wahrscheinlich globalnicht das Beste ist, viel davon zu verwenden.
globalwürde dazu führen, dass sich die Funktion anders verhält - alle Aufrufe von conf_decorator würden dann dieselbe Variable c_kwargs verwenden. Ich glaube, Python 3 hat das nonlocalSchlüsselwort hinzugefügt , um dieses Problem zu beheben, und das würde funktionieren.
Außerdem kann die Diktatinstanz manchmal eine Unterklasse von Dikt sein ( defaultdictzum Beispiel). In diesem Fall wird die Verwendung clearbevorzugt, da wir uns nicht an den genauen Typ des Diktats erinnern müssen und auch doppelten Code vermeiden müssen (Kopplung der Clearing-Linie mit der Initialisierungslinie).
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)