2013-07-29 71 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()] 
>>>