Clear ()和 Python 中赋值{}之间的区别

在 python 中,调用 clear()和将 {}分配给字典有区别吗? 如果有,是什么? 示例: < pre > < code > d = {“ stuff”: “ things”} 这边 D = {} # vs 这样

108859 次浏览

如果你有另一个变量也引用同一个字典,那就有很大的不同:

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

这是因为分配 d = {}将创建一个新的空字典,并将其分配给 d变量。这使得 d2指向旧的字典,其中的项目仍然在其中。然而,d.clear()清除了 dd2都指向的同一个字典。

d = {}将为 d创建一个新实例,但所有其他引用仍将指向旧内容。 d.clear()将重置内容,但对同一实例的所有引用仍将是正确的。

除了在其他答案中提到的差异之外,还有速度上的差异。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

作为前面提到的事情的一个例子:

>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L

除了@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 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.clear()代替 c_kwargs = {}

如果有人想出一个更实际的例子,请随意编辑这篇文章。

如果原始对象不在作用域中,变异 方法总是有用的:

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


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

重新分配字典将创建一个新对象,而不会修改原来的对象。

此外,有时候 dict 实例可能是 dict 的一个子类(例如 defaultdict)。在这种情况下,首选使用 clear,因为我们不需要记住 dict 的确切类型,也避免重复代码(将清除行与初始化行耦合在一起)。

x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)