2013-07-29 78 views
0

这似乎是一个疑难杂症对我来说,我不能算出这个Python列表同步更新

>>> from collections import Counter 
>>> tree = [Counter()]*3 
>>> tree 
[Counter(), Counter(), Counter()] 
>>> tree[0][1]+=1 
>>> tree 
[Counter({1: 1}), Counter({1: 1}), Counter({1: 1})] 

为什么更新一个计数器更新的一切吗?

+3

因为该行的'[计数器()] * 3'。你没有创建3个独特的计数器。您正在创建一个带有三个对同一个Counter对象的引用的列表。 –

+1

你有一个三个引用到同一个计数器的列表。改为尝试列表理解。 –

回答

5

使用[x] * 3,列表中引用同一项目(x)三次。

>>> from collections import Counter 
>>> tree = [Counter()] * 3 
>>> tree[0] is tree[1] 
True 
>>> tree[0] is tree[2] 
True 
>>> another_counter = Counter() 
>>> tree[0] is another_counter 
False 

>>> for counter in tree: print id(counter) 
... 
40383192 
40383192 
40383192 

当Waleed Khan评论时使用列表理解。

>>> tree = [Counter() for _ in range(3)] 
>>> tree[0] is tree[1] 
False 
>>> tree[0] is tree[2] 
False 

>>> for counter in tree: print id(counter) 
... 
40383800 
40384104 
40384408 
+0

另外'在树计数器:打印ID(计数器)'应该给一个更好的了解。 –

+0

@limelights,谢谢你的建议。我补充说。 – falsetru

1

[Counter()]*3产生包含相同Counter实例3倍的列表。您可以使用

[Counter() for _ in xrange(3)] 

创建的3周独立Counter的List。

>>> from collections import Counter 
>>> tree = [Counter() for _ in xrange(3)] 
>>> tree[0][1] += 1 
>>> tree 
[Counter({1: 1}), Counter(), Counter()] 

一般来说,当乘以元素是可变的列表时,你应该小心谨慎。

1

tree = [Counter()]*3创建一个计数器和三个引用它;

c = Counter() 
tree = [c, c, c] 

你想三个计数器:因为你可以把它写

>>> from collections import Counter 
>>> tree = [Counter() for _ in range(3)] 
>>> tree[0][1]+=1 
>>> tree 
[Counter({1: 1}), Counter(), Counter()] 
>>>