I am using Python 3.4.1 and I was wondering about the following situation:
Given an array of counters
cnt = [Counter()] * n I want to add some items in a specific position, so I do
cnt[i] += Counter(x) For the construction "+=", I was trying to do
cnt[i] = cnt[i] + Counter(x) But, instead of what I expected, I received something equivalent to
for i in range(0, n): cnt[i] = cnt[i] + Counter(x) In other words, it added all my counters in the array.
- Is this behavior (add every item of the array) common in Python? Am I interpreting anything wrong?
- There is a correct/easy/safe way to write what I desired?
- Is this a bug of the version?
An short example:
from collections import Counter text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." cnt = [Counter()] * 2 i = 0 for c in text: cnt[i] += Counter(c) # cnt[i] = cnt[i] + Counter(c) i = (i+1) % 2 for i in range(0, 2): print(cnt[i], i) Output:
Counter({' ': 7, 'i': 6, 'e': 5, 't': 5, 'o': 4, 's': 4, 'm': 3, 'r': 3, 'c': 3, 'u': 2, 'p': 2, 'a': 2, 'l': 2, 'd': 2, 'n': 2, '.': 1, 'g': 1, 'L': 1, ',': 1}) 0 Counter({' ': 7, 'i': 6, 'e': 5, 't': 5, 'o': 4, 's': 4, 'm': 3, 'r': 3, 'c': 3, 'u': 2, 'p': 2, 'a': 2, 'l': 2, 'd': 2, 'n': 2, '.': 1, 'g': 1, 'L': 1, ',': 1}) 1 Expected output:
Counter({'t': 4, 'i': 3, 'r': 3, 's': 2, 'e': 2, 'm': 2, 'c': 2, 'n': 2, 'a': 2, 'l': 2, ',': 1, 'd': 1, ' ': 1, 'L': 1}) 0 Counter({' ': 6, 'o': 4, 'i': 3, 'e': 3, 's': 2, 'u': 2, 'p': 2, '.': 1, 't': 1, 'g': 1, 'd': 1, 'm': 1, 'c': 1}) 1
cntarray refer to the same counter. You didn't make a copy of it when you used the*operator.*other times and it works well, ie, make different copies.+=differently.__iadd__was added to Counter in a later Python version. I don't remember which, but 3.4 should have it.