0

这对我来说似乎是一个陷阱,我无法弄清楚

>>> 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})]

为什么更新一个计数器会更新所有内容?

4

3 回答 3

5

使用[x] * 3,列表引用相同的 item( 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
于 2013-07-29T19:02:01.330 回答
1

[Counter()]*3生成一个包含相同 Counter实例 3 次的列表。您可以使用

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

创建一个包含 3 个独立Counters 的列表。

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

通常,在将元素可变的列表相乘时应该小心。

于 2013-07-29T19:02:32.647 回答
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()]
>>> 
于 2013-07-29T19:02:53.517 回答