I have some code where I make a dictionary and each value is the list [0,0]. I found that incrementing any list index would increment each value's corresponding index; i.e. d[key][0] += 1 would increment each other list's 0 index.
I assumed Python's shallow copying of the list was to blame, since my dictionary was constructed using dict.fromkeys(keys, [0,0]). However, I had the same problem when using copy.deepcopy on the list.
I then tried dictionary comprehension: {key:[0,0] for key in keys}. This works as I would expect; modifying one list does not affect the others.
Since I've found a solution to this issue, my actual question is why this is the case. It seems that either I'm mistaken about how deepcopy works or that it's irrelevant to the issue at hand, but I don't know what else would cause this.
This is a full snippet that reproduces the behavior:
import copy
keys = [i for i in range(5)]
l = [0,0]
d = dict.fromkeys(keys, copy.deepcopy(l))
#d = {key:[0,0] for key in keys} # this approach works as expected
d[0][0] += 1
print(d)
# expected: {0: [1, 0], 1: [0, 0], 2: [0, 0], 3: [0, 0], 4: [0, 0]}
# actual: {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0], 4: [1, 0]}
In this case,
deepcopyis not helping the issue, it'sdict.fromkeysfunctionality. From the documentation at https://docs.python.org/3/library/stdtypes.html#dict.fromkeysYou are passing in a single list to
fromkeysfor the value argument. So every key in the dict refers to one list, which just happened to be deepcopied froml.So it seems like your dict comprehension is the recommended method. Since you are making a new list for each element, with
[0, 0], they stay independent.