0

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.

duhaime
  • 25,611
  • 17
  • 169
  • 224
  • 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]`. – NobbyNobbs Mar 19 '21 at 12:21
  • Woof you nailed it. Can you please make this an answer so I can accept it? – duhaime Mar 19 '21 at 12:34
  • Yes, sure I can. – NobbyNobbs Mar 19 '21 at 12:46

1 Answers1

0

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

NobbyNobbs
  • 1,341
  • 1
  • 11
  • 17