0

This seems to be a gotcha for me, I couldnt figure this out

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

Why does updating one Counter updates everything?

FUD
  • 5,114
  • 7
  • 39
  • 61
  • 3
    Because of this line `[Counter()]*3`. You're not creating 3 unique Counters. You're creating one list with three references to the same Counter object. – Henrik Andersson Jul 29 '13 at 18:59
  • 1
    You've got a list with three references to the same counter. Try a list comprehension instead. – Waleed Khan Jul 29 '13 at 19:00

3 Answers3

5

Using [x] * 3, the list references same item(x) three times.

>>> 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

Use list comprehension as Waleed Khan commented.

>>> 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
falsetru
  • 357,413
  • 63
  • 732
  • 636
1

[Counter()]*3 produces a list containing the same Counter instance 3 times. You can use

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

to create a list of 3 independent Counters.

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

In general, you should be cautious when multiplying lists whose elements are mutable.

arshajii
  • 127,459
  • 24
  • 238
  • 287
1

tree = [Counter()]*3 creates one counter and three references to it; you could write it as:

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

You want three counters:

>>> from collections import Counter
>>> tree = [Counter() for _ in range(3)]
>>> tree[0][1]+=1
>>> tree
[Counter({1: 1}), Counter(), Counter()]
>>> 
phihag
  • 278,196
  • 72
  • 453
  • 469