2

I had the following dictionary:

ref_range = range(0,100)
aas = list("ACDEFGHIKLMNPQRSTVWXY*")
new_dict = {}
new_dict = new_dict.fromkeys(ref_range,{k:0 for k in aas})

Then I added a 1 to a specific key

new_dict[30]['G'] += 1

>>>new_dict[30]['G']
1

but

>>>new_dict[31]['G']
1

What is going on here? I only incremented the nested key 30, 'G' by one.

Note: If I generate the dictionary this way:

new_dict = {}
for i in ref_range:
   new_dict[i] = {a:0 for a in aas}

Everything behaves fine. I think this is a similar question here, but I wanted to know a bit about why this happening rather than how to solve it.

Community
  • 1
  • 1
jwillis0720
  • 4,329
  • 8
  • 41
  • 74
  • 1
    Existing answer is correct, just providing the one-liner for making `new_dict`: `new_dict = {i: dict.fromkeys(aas, 0) for i in ref_range}`. Alternatively, make a template `dict`: `template = dict.fromkeys(aas, 0)`, then shallow copy it over and over: `new_dict = {i: template.copy() for i in ref_range}` – ShadowRanger Feb 24 '16 at 02:38

1 Answers1

2

fromkeys(S, v) sets all of the keys in S to the same value v. Meaning that all of the keys in your dictionary new_dict refer to the same dictionary object, not to their own copies of that dictionary.

To set each to a different dict object you cannot use fromkeys. You need to just set each key to a new dict in a loop.

Besides what you have you could also do

{i: {a: 0 for a in aas} for i in ref_range}
Jason S
  • 13,538
  • 2
  • 37
  • 42
  • 1
    do you think there should be a warning generated or something? I mean, its not very intuitive right off the bat. – jwillis0720 Feb 24 '16 at 07:40