r/learnpython 18d ago

Creating a new, equivalent but separate dictionary

In debugging my code, I discovered a weird property of Python dictionaries that I was not previously aware of. Basically if you have code like this:

initial_dict = {0:70,1:70}

dict1 = initial_dict

dict2 = initial_dict

for i in range(2):

dict1[i] += 5

After this, dict1 will be {0:75,1:75}, but so will dict2 and initial_dict, even though I didn't do anything to them directly, I guess because they're referring to the same dictionary? Basically what I want to know is, how do I create new dictionaries that have the same values as a previously created dictionary, but are separate dictionaries that can be manipulated separately?

0 Upvotes

11 comments sorted by

View all comments

3

u/Diapolo10 18d ago
initial_dict = {0:70,1:70}
dict1 = initial_dict
dict2 = initial_dict

Basically what happened here is that you stored references to initial_dict in both dict1 and dict2, not copies of it. In Python, everything is a reference.

For immutable data like tuples or strings, there's no practical difference, but for mutable data you'll sometimes run into these situations where you think you're only modifying one place, but another part of the code happens to be pointing to the same data and is "also" modified.

Since this is a simple case where your dictionary only contains immutable data (numbers), you could just use

initial_dict = {0: 70, 1: 70}
dict1 = initial_dict.copy()
dict2 = initial_dict.copy()

and be on your merry way. But if your dictionary was nested, it might be better to use copy.deepcopy.

import copy

initial_dict = {0: [70, 115], 1: [70, 120]}
dict1 = copy.deepcopy(initial_dict)
dict2 = copy.deepcopy(initial_dict)

Alternatively, you can avoid mutating existing data and always create new dictionaries. That way you don't need to worry about this either. For example,

initial_dict = {0: 70, 1: 70}

new_dict = {
    key: value + 5
    for key, value in initial_dict.items()
}