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 ddeğ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 dve d2her 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_kwargsmuhtemelen hayır çalışır? Her ne kadar muhtemelen globalbir sürü kullanmak için en iyi şey değil.
globaliş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 nonlocalbu 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, cleardiktenin 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)