В python есть ли разница между вызовом clear()и назначением {}словаря? Если да, что это? Пример:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
В python есть ли разница между вызовом clear()и назначением {}словаря? Если да, что это? Пример:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
Ответы:
Если у вас есть другая переменная, также ссылающаяся на тот же словарь, есть большая разница:
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
Это связано с тем, что назначение d = {}создает новый пустой словарь и присваивает его dпеременной. Это оставляет d2указание на старый словарь с предметами, все еще в нем. Однако, d.clear()очищает и тот же словарь , что dи d2как точку.
В дополнение к различиям, упомянутым в других ответах, есть также разница в скорости. d = {} более чем в два раза быстрее:
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 = {}должна быть более быстрой, поскольку очистка целого может быть оставлена для сборщика мусора на потом.
В дополнение к ответу @odano, кажется, использовать d.clear()быстрее, если вы хотели бы очистить голос много раз.
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)
Результат:
20.0367929935
19.6444659233
Методы мутации всегда полезны, если исходный объект не находится в области видимости:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
Повторное назначение словаря создаст новый объект и не изменит исходный.
Одна вещь, не упомянутая, является вопросами определения объема. Не очень хороший пример, но вот случай, когда я столкнулся с проблемой:
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
Решение состоит в том, чтобы заменить c_kwargs = {}сc_kwargs.clear()
Если кто-то придумает более практичный пример, не стесняйтесь редактировать этот пост.
global c_kwargsвероятно, тоже будет работать нет? Хотя, вероятно global, не самая лучшая вещь для использования.
globalприведет к тому, что функция будет вести себя по-разному - все вызовы conf_decorator будут совместно использовать одну и ту же переменную c_kwargs. Я считаю, что Python 3 добавил nonlocalключевое слово для решения этой проблемы, и это будет работать.
Кроме того, иногда экземпляр dict может быть подклассом dict ( defaultdictнапример). В этом случае использование clearявляется предпочтительным, поскольку нам не нужно запоминать точный тип dict, а также избегать дублирования кода (связывание строки очистки с линией инициализации).
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)