user3157132 user3157132 - 2 months ago 9
Python Question

Adding a dict as a value to another dict is overwriting the previous value

I have a piece of python code like below ( I am sorry that I couldn't paste my actual code because its very big)

final_dict = {}
default_dict = some_data

for dict in list_of_dicts:
# I am getting list_of_dicts from a json file
resultant_dict = merge_dicts(dict, default_dict)
id = return_value_from_a_function(resultant_dict)
final_dict[id] = resultant_dict # id will be different in each loop


So the final_dict is supposed to have id's as keys and resultant_dict's as values. My problem is that at the end of the for loop, all my values in the final_dict are same as the last value of resultant_dict. I think it is overwriting the previous values (may be because its a reference). How to solve this issue..?

EDIT 1: merge_dicts actually creates the union of two dicts. When I print resultant_dict, it prints different dict each time, as expected. But when I assign it as a value to final_dict, it is modifying all the previous values with the latest one.

EDIT 2: All the input data is a dict which I am getting from a json file. The final dict should look something like below

final_dict = {
id1 : dict1,
id2 : dict2
}


But I am getting like below ( It is overwriting all the values with the latest dict value)

final_dict = {
id1 : dict2,
id2 : dict2
}


EDIT 3: This is how merge_dicts work

def merge_dicts(tmp1, tmp2):
'''
merges tmp2 into tmp1
'''
for key in tmp2:
if key in tmp1:
if isinstance(tmp1[key], dict) and isinstance(tmp2[key], dict):
merge_dicts(tmp1[key], tmp2[key])
else :
tmp1[key] = tmp2[key]
else:
tmp1[key] = tmp2[key]
return tmp1

Answer

Why don't you generate the id first and then straight away assign the merge_dicts value there?

for dict in list_of_dicts:
    # I am getting list_of_dicts from a json file
    id = return_value_from_a_function
    final_dict[id] = merge_dicts(dict, default_dict)

EDIT: Since return_value_from_a_function function makes use of resultant_dict, it seems the return_value_from_a_function modifies the resultant_dict.

from copy import deepcopy

for input_dict in list_of_dicts:
    resultant_dict = {}
    resultant_dict = merge_dicts(input_dict, default_dict)
    # I am getting list_of_dicts from a json file
    value_dict = deepcopy(resultant_dict)
    id = return_value_from_a_function(resultant_dict)
    final_dict[id] = value_dict
Comments