Search code examples
pythondictionarycounter

Why does a Python collections.Counter get mutated when its values are referenced


I'm not quite sure what's happening here:

from collections import defaultdict, Counter

c1 = defaultdict(Counter)
c2 = defaultdict(Counter)

c1[1][2] = 3
c1[2][3] = 4

keys = c1.keys()

for i in keys:
  c2[i] = c1[i]
  
  for k in keys:
    if k < i:
      c2[i] += c1[k]
      
c1

That displays:

defaultdict(collections.Counter,
            {1: Counter({2: 3}), 2: Counter({3: 4, 2: 3})})

Why does c1 get mutated? I know one can eliminate the mutation by changing c2[i] = c1[i] to c2[i] += c1[i]. But my goal is to understand why the snippet above mutates c1.


Solution

  • Here you have two dicts of counters, then you create additional link to existing counter from the first dict in the second, so c2[i] is c1[i] == True, it's the same counter instance. You could use

    c2[i] = c1[i].copy()
    

    if you want, it's more explicit than c2[i] += c1[i].