W python, czy istnieje różnica między wywołaniem clear()
i przypisanie {}
do słownika? Jeśli tak, co to jest? Przykład: Różnica między dict.clear() i przypisywanie {} w Python
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
W python, czy istnieje różnica między wywołaniem clear()
i przypisanie {}
do słownika? Jeśli tak, co to jest? Przykład: Różnica między dict.clear() i przypisywanie {} w Python
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Jeśli masz inny zmienna również odnoszące się do tego samego słownika, istnieje duża różnica:
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
To dlatego przypisanie d = {}
tworzy nową, pustą słownika i przypisuje go do d
zmienna. Pozostawia to d2
wskazujące na stary słownik z wciąż znajdującymi się w nim elementami. Jednak d.clear()
usuwa ten sam słownik, z którym oba są oznaczone jako d
i .
d = {}
utworzy nowe wystąpienie dla d
, ale wszystkie inne odniesienia będą nadal wskazywać na starą zawartość. d.clear()
zresetuje zawartość, ale wszystkie odniesienia do tej samej instancji będą nadal poprawne.
Oprócz różnic wymienionych w innych odpowiedziach występuje również różnica prędkości. d = {} jest ponad dwa razy szybciej:
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
To naprawdę nie jest ważny test prędkości dla wszystkich przypadków, ponieważ dyktat jest pusty. Wydaje mi się, że zrobienie dużego dicta (lub przynajmniej trochę treści) przyniosłoby znacznie mniejszą różnicę w wydajności ... plus podejrzewam, że śmieciarz mógłby dodać trochę własnego bólu do d = {} (?) – Rafe
@Rafe: I Myślę, że chodzi o to, że jeśli wiemy, że żadna inna zmienna nie wskazuje na słownik d, to ustawienie 'd = {}' powinno być szybsze, ponieważ czyszczenie całości może być pozostawione na Garbage Collector na później. – ViFI
Jako ilustracja na rzeczy już wspomniane wcześniej:
>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L
To pokazuje, że '.clear' modyfikuje obiekt, ale' = {} 'tworzy nowy obiekt. – wizzwizz4
oprócz @odano „s odpowiedź wydaje się, używając d.clear()
jest szybciej, jeśli chciałbyś wyczyścić dyktę wiele razy.
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)
Wynikiem jest:
20.0367929935
19.6444659233
Nie jestem pewien, czy różnica jest znacząca. W każdym razie na mojej maszynie wyniki są odwrotne! – Aristide
Jedno nie jest wymienione kwestie określania zakresu. Nie jest to świetny przykład, ale tutaj jest przypadek, gdy wpadłem na ten problem:
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
Rozwiązaniem jest zastąpienie c_kwargs = {}
z c_kwargs.clear()
Jeśli ktoś uważa się bardziej praktyczny przykład, nie krępuj się, aby edytować ten post .
'global c_kwargs' prawdopodobnie też by działało nie? Chociaż prawdopodobnie "globalne" nie jest najlepszą rzeczą, z której można korzystać bardzo często. – fantabolous
@fantabolous za pomocą 'global' spowodowałby, że funkcja zachowywałaby się inaczej - wszystkie wywołania conf_decorator miałyby wówczas wspólną tę samą zmienną c_kwargs. Wierzę, że Python 3 dodał słowo kluczowe "nielokalny", aby rozwiązać ten problem, a to by działało. – Ponkadoodle
Mutowanie metodami zawsze Przydatne jeśli obiekt nie znajduje się w zakresie:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
ponownego przydzielania słownika by utworzyć nowy przedmiot i nie modyfikować pierwotnego.
Ponadto, czasami instancja dict może być podklasą dyktowania (na przykład: defaultdict
). W takim przypadku preferowane jest używanie clear
, ponieważ nie musimy pamiętać dokładnego typu dyktanda, a także unikamy powtarzania kodu (połączenie linii czyszczącej z linią inicjalizacji).
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)
Dzięki. To ma sens. Nadal muszę się przyzwyczaić do sposobu myślenia, który = tworzy odniesienia w pythonie ... – Marcin
= kopiuje odniesienia do nazw. W pythonie nie ma zmiennych, tylko obiekty i nazwy. – tzot
Chociaż twoje stwierdzenie "bez zmiennych" jest pedantycznie prawdziwe, nie jest tu zbyt pomocne. Dopóki dokumentacja w języku Python nadal mówi o "zmiennych", nadal używam terminu: http://docs.python.org/reference/datamodel.html –