How to properly copy a list of dictionaries in python?

I’ve been having trouble with a script and I isolated the issue to the fact that my for loops are somehow modifying an unrelated list (as far as I can tell). I replicated the result with this piece of code:

list1 = [{"key1": 1, "key2": 2}]

list2 = list(list1)

print "ID of list1: " + str(id(list1))
print "ID of list2: " + str(id(list2))
print "Contents of list1: " + str(list1)
print "Contents of list2: " + str(list2)

list2[0]["key1"] = 999
		
print "ID of list1: " + str(id(list1))
print "ID of list2: " + str(id(list2))
print "Contents of list1: " + str(list1)
print "Contents of list2: " + str(list2)

It returns this:
image

This makes absolutely no sense to me, because the IDs of the lists are different, but the code modifying list2 somehow also modifies list1…

This piece of code works as expected:

list1 = [1, 2]
list2 = list(list1)
list2[0] = 999
print list1
print list2

returning:
image

Does this have something to do with dictionaries? I am very confused…

If it is the dictionaries, is there a proper way to copy a list of dictionaries to actually create two different lists?

I would appreciate some insight.

I think it has to do with deep vs shallow copying. I only know this because I ran into a very similar situation earlier this year.

When you say list2 = list1, list2 is a reference to list1, so any changes you make to list1 will also modify list2.

import copy
list2 = copy.deepcopy(list1)

Try this out.

2 Likes

Thanks for the reply. That’s what I though at first as well, but I’m not simply doing list2 = list1. But rather list2 = list(list1) which doesn’t copy the reference, but actually makes another list.
The IDs of both lists are different in the above example, so the code should be referencing different lists.

I tried copy.deepcopy() and it worked. Thank You!

2 Likes

Actually, it makes a different list containing different references to the same elements.
The key thing here is that your list contains references, not values. When copying the list, even if it’s a brand new one, the things inside still reference the same things.

Imagine copying a list of pointers. You end up with 2 different lists, that contain different pointers, but that point to the same place. Now, if you tried list2[0] = '999', that won’t change list1[0], only assign 999 to list2[0].
BUT, list2[0][0] = 999 WILL modify the thing that was pointed at by both list1[0] and list2[0].

If you look back at your first code snippet, you’ll see you’re using list2[0]['key1'] = 999. You’re not modifying the first element of list2, you’re modifying the object referenced by the first element of list2. Which happens to also be referenced by the first element of list1.

1 Like

This makes sense. Thank You for the reply.