dict.clear()和Python中赋值{}之间的区别
在python中,调用clear()
和赋值给字典有什么不同? 如果是,那是什么? 例:
d = {"stuff":"things"} d.clear() #this way d = {} #vs this way
如果你有另一个variables也是指同一个字典,那么有一个很大的区别:
>>> d = {"stuff": "things"} >>> d2 = d >>> d = {} >>> d2 {'stuff': 'things'} >>> d = {"stuff": "things"} >>> d2 = d >>> d.clear() >>> d2 {}
这是因为赋值d = {}
会创build一个新的空字典并将其赋值给d
variables。 这使得d2
指向旧字典,其中的项目仍在其中。 但是, d.clear()
清除d
和d2
指向的同一个字典。
d = {}
将为d = {}
创build一个新的实例,但所有其他引用仍将指向旧的内容。 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
除了@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
作为前面已经提到的事情的例证:
>>> a = {1:2} >>> id(a) 3073677212L >>> a.clear() >>> id(a) 3073677212L >>> a = {} >>> id(a) 3073675716L
如果原始对象不在范围内,则变异方法总是有用的:
def fun(d): d.clear() d["b"] = 2 d={"a": 2} fun(d) d # {'b': 2}
重新分配字典将创build一个新的对象,不会修改原来的。
有一件事没有提到的是范围问题。 不是一个很好的例子,但是我遇到了这个问题:
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()
replacec_kwargs = {}
如果有人想一个更实际的例子,请随时编辑这篇文章。
另外,字典实例有时也可能是字典的一个子类(例如defaultdict
)。 在这种情况下,使用clear
是首选,因为我们不必记住字典的确切types,也可以避免重复代码(将清除行与初始化行结合)。
x = defaultdict(list) x[1].append(2) ... x.clear() # instead of the longer x = defaultdict(list)