Search code examples
pythondictionarydefaultdict

Updating specific value in one nested defaultdict but not in other defaultdicts


I built a three-level defaultdict that looks like this:

data_dict = 
{
    "5uz7_R": {
        "section1": {
            "=": 0,
            "-": 0,
            ".": 0,
            "+": 0,
            "|": 0,
            "gaps": 0
        },
        "section2": {
            "=": 0,
            "-": 0,
            ".": 0,
            "+": 0,
            "|": 0,
            "gaps": 0
        }
    },
    "4l6r_A": {
        "section1": {
            "=": 0,
            "-": 0,
            ".": 0,
            "+": 0,
            "|": 0,
            "gaps": 0
        },
        "section2": {
            "=": 0,
            "-": 0,
            ".": 0,
            "+": 0,
            "|": 0,
            "gaps": 0
        }
    }
}

My goal was to use for loops and if statements to update ONE of the integer values depending on where I am in the loops and which character (=,-,+,...) is found as I iterate over a string that contains these characters.

I have several separate lists that have the items I want to iterate over, and corresponding items have corresponding indexes (it's a long story...). So I create a string variable at each loop that corresponds to the successive dictionnary keys I want to find to update the deepest-nested value depending on the if statement. It looks something like this:

for i in list1:
    dict_lvl1 = a_function_of_i  # a string, like "5uz7_R"
    for j in list2:
        dict_lvl2 = a_function_of_j  # a string, like "section1"
        for n in range(x):
            if string[n] == '=':
                data_dict[dict_lvl1][dict_lvl2]["="] += 1
            elif string[n] == '-':
                data_dict[dict_lvl1][dict_lvl2]["-"] += 1
            ...

Problem is: if '=' (or any of the lvl3 characters) is encountered, the value of "=" gets updated everywhere.

I have a feeling that "main_dict[variable][variable]["character"] += 1" is intrinsically flawed, but I want to make sure there is no way to make the code work as is (since it serves other purposes before getting to that stage).

I hope this is somewhat understandable, and I sincerely apologize if it isn't!

****EDIT****

data_dict is constructed with collections.defaultdict by fetching the key values from existing lists' items:

symbol_dict = defaultdict(int)
section_dict = defaultdict(dict)
data_dict = defaultdict(dict)

[symbol_dict[i] for i in symbol_list]

for j in section_list:
    section_dict[j]=symbol_dict

for k in pdb_list:
    data_dict[k] = section_dict

print(json.dumps(data_dict, indent=4))

The print statement generates data_dict as shown at the beginning.


Solution

  • To me, it looks like you are assigning the same symbol_dict to all section_dicts. Try constructing it as:

    from copy import deepcopy
    
    for j in section_list:
        section_dict[j]=deepcopy(symbol_dict)
    
    for k in pdb_list:
        data_dict[k] = deepcopy(section_dict)