'Problem with changing nested dict values in Python

I have a problem trying to change values in a nested dictionary:

dictionary = {"2000": {"1.1.1.": 1, "1.2.3.": 5, "1.2.1.": 1}, "2001": {"1.2.3.": 5, "1.1.4.5.": 1}, "2002": {"1.1.1.": 1, "1.2.3.": 10}, "2003": {"1.1.1.": 5, "1.2.3.4.5.6.": 10}}
hierarchies = {"1.1.1.", "1.2.3."}

peryear_values = dict.fromkeys(list(sorted(dictionary.keys())), 0) 
h_values = dict.fromkeys(list(hierarchies), peryear_values)  
for hierarchy in hierarchies:
    for year, values in sorted(dictionary.items()):
        if hierarchy in values.keys():
            print("\nThe hierarchy: ", hierarchy)
            print("In year: ", year)
            print("The value: ", values[hierarchy])
            h_values[hierarchy][year] = values[hierarchy]
print(h_values)

The desired output:

{"1.1.1.": {"2000": 1, "2001": 0, "2002": 1, "2003": 5}, "1.2.3": {"2000": 5, "2001": 5, "2002": 10, "2003": 0}}

The output that I get:

{'1.1.1.': {'2000': 5, '2001': 5, '2002': 10, '2003': 5}, '1.2.3.': {'2000': 5, '2001': 5, '2002': 10, '2003': 5}}

It seems that for each iteration the value of both "hierarchy" keys changes, instead of respecting the change in the specific one. Is there something I'm doing wrong?

I'm running python 3.9.7 and conda 4.12.0



Solution 1:[1]

Yes. There is only one peryear_values dict in your program. When you create h_values, you are just storing multiple references to that one dictionary. You can't use dict.fromkeys for this. You'll have to use a loop and use peryear_values.copy().

h_values = dict( (h, peryear_values.copy()) for h in hierarchies )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tim Roberts