Python'da, sözlüğü arama clear()
ve atama arasında bir fark var {}
mı? Eğer evet ise, bu nedir? Misal:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Python'da, sözlüğü arama clear()
ve atama arasında bir fark var {}
mı? Eğer evet ise, bu nedir? Misal:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Yanıtlar:
Aynı sözlüğe başvuran başka bir değişkeniniz varsa, büyük bir fark vardır:
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
Bunun nedeni atamanın d = {}
yeni, boş bir sözlük oluşturması ve d
değişkene atamasıdır. Bu d2
, hala içindeki öğelerle eski sözlüğe işaret eder. Ancak, d.clear()
aynı sözlüğü siler d
ve d2
her ikisi de işaret eder.
Diğer cevaplarda belirtilen farklılıklara ek olarak, bir hız farkı da vardır. d = {} iki kat daha hızlı bitti:
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 = {}
daha hızlı olmalıdır çünkü bütün temizlik daha sonra Çöp Toplayıcısına bırakılabilir.
@Odano'nun cevabına ek olarak, bu dikdörtgeni d.clear()
birçok kez temizlemek isterseniz kullanmak daha hızlı görünüyor .
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)
Sonuç:
20.0367929935
19.6444659233
Orijinal nesne kapsamda değilse, mutasyon yöntemleri her zaman yararlıdır:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
Sözlüğün yeniden atanması yeni bir nesne oluşturur ve orijinalini değiştirmez.
Bahsetmediğim bir şey, kapsam belirleme sorunudur. Harika bir örnek değil, ama burada sorunla karşılaştığım durum:
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
Çözelti değiştirmektir c_kwargs = {}
ilec_kwargs.clear()
Birisi daha pratik bir örnek düşünürse, bu yayını düzenlemek için çekinmeyin.
global c_kwargs
muhtemelen hayır çalışır? Her ne kadar muhtemelen global
bir sürü kullanmak için en iyi şey değil.
global
işlev farklı davranır - conf_decorator'a yapılan tüm çağrılar aynı c_kwargs değişkenini paylaşır. Python 3'ün nonlocal
bu sorunu çözmek için anahtar kelimeyi eklediğine inanıyorum ve bu işe yarayacaktır.
Buna ek olarak, bazen dict örneği bir dict alt sınıfı olabilir ( defaultdict
örneğin). Bu durumda, clear
diktenin tam tipini hatırlamak zorunda olmadığımız ve yinelenen koddan (temizleme hattını başlangıç çizgisine bağlayan) kullanmak zorunda olmadığımız için kullanmak tercih edilir.
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)