Разница между dict.clear () и назначением {} в Python - PullRequest
154 голосов
/ 16 декабря 2008

Есть ли в python разница между вызовом clear() и присвоением {} словарю? Если да, что это? Пример:

d = {"stuff":"things"}
d.clear()   #this way
d = {}      #vs this way

Ответы [ 8 ]

265 голосов
/ 16 декабря 2008

Если у вас есть другая переменная, также ссылающаяся на тот же словарь, есть большая разница:

>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}

Это потому, что назначение d = {} создает новый пустой словарь и присваивает его переменной d. Это оставляет d2, указывающий на старый словарь с элементами, все еще находящимися в нем. Однако d.clear() очищает тот же словарь, на который указывают d и d2.

29 голосов
/ 16 декабря 2008

d = {} создаст новый экземпляр для d, но все остальные ссылки будут по-прежнему указывать на старое содержимое. d.clear() сбросит содержимое, но все ссылки на один и тот же экземпляр будут по-прежнему правильными.

21 голосов
/ 16 декабря 2008

В дополнение к различиям, упомянутым в других ответах, также есть разница в скорости. 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
7 голосов
/ 25 декабря 2012

В дополнение к ответу @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
6 голосов
/ 25 ноября 2015
Методы

Mutating всегда полезны, если исходный объект находится вне области действия:

def fun(d):
    d.clear()
    d["b"] = 2

d={"a": 2}
fun(d)
d          # {'b': 2}

Повторное назначение словаря создаст новый объект и не изменит исходного.

6 голосов
/ 08 декабря 2011

В качестве иллюстрации для уже упомянутых вещей:

>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L
4 голосов
/ 26 августа 2013

Единственное, что не упомянуто, это проблемы с областями видимости. Не очень хороший пример, но вот случай, когда я столкнулся с проблемой:

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()

Если кто-то придумает более практичный пример, не стесняйтесь редактировать этот пост.

1 голос
/ 03 июля 2017

Кроме того, иногда экземпляр dict может быть подклассом dict (например, defaultdict). В этом случае использование clear является предпочтительным, так как нам не нужно запоминать точный тип dict, а также избегать дублирования кода (связывание строки очистки с линией инициализации).

x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...