Friday, December 19, 2025

Record Copy Issues · Ponderings of an Andy


Introduction

This downside is not restricted to solely records. Any mutable object in Python might be impacted by this “gotcha”. The issue is setting one mutable object equal to a different would not make a replica. It assigns a brand new variable to the identical object as the unique. Let’s have a look and see how this seems.

The First Gotcha

The primary instance is fairly easy. Let’s make a replica of our record

>>> list1 = [1,2,3,4,5]
>>> list2 = list1
>>> list1
[1, 2, 3, 4, 5]
>>> list2
[1, 2, 3, 4, 5]

That appears like I’ve two lists, each with the identical set of values. However, let’s modify the second record and alter the primary aspect within the record to be 6

>>> list2
[6, 2, 3, 4, 5]

However what about list1? It additionally has modified.

>>> list1
[6, 2, 3, 4, 5]

That is occuring as a result of, as talked about, list2 is assigned to the identical object as list1. Any change to both, modifications the article that each are assigned to.

>>> print(f"list1 id: {id(list1)}")
list1 id: 1497534800448
>>> print(f"list2 id: {id(list2)}")
list2 id: 1497534800448

The First Resolution

This may be solved just a few other ways. The necessary take away, although, is that you must create a brand new object with the unique values. I can assume of some methods to deal with this. This text would not think about efficiency for these primary lists.

One possibility is to make the most of the record() methodology and go it the preliminary values from list1

>>> list3 = record(list1)
>>> list3
[6, 2, 3, 4, 5]
>>> list3[0] = 0
>>> list3
[0, 2, 3, 4, 5]
>>> list1
[6, 2, 3, 4, 5]
>>> print(f"list1 id: {id(list1)}")
list1 id: 1497534800448
>>> print(f"list3 id: {id(list3)}")
list3 id: 1497531282368

A second possibility is to slice() all the unique record into a brand new variable.

>>> list4 = list1[:]
>>> list4
[6, 2, 3, 4, 5]
>>> list4[0] = 0
>>> list4
[0, 2, 3, 4, 5]
>>> list1
[6, 2, 3, 4, 5]
>>> print(f"list1 id: {id(list1)}")
list1 id: 1497534800448
>>> print(f"list4 id: {id(list4)}")
list4 id: 1497534798208

Lastly, the record object has a copy() methodology that you may make the most of.

>>> list5 = list1.copy()
>>> list5[0] = 0
>>> list5
[0, 2, 3, 4, 5]
>>> list1
[6, 2, 3, 4, 5]
>>> print(f"list1 id: {id(list1)}")
list1 id: 1497534800448
>>> print(f"list5 id: {id(list5)}")
list5 id: 1497534799552

With every of those three choices, you’ll be able to see that we created new objects as a result of every has a singular object id. Altering one among these copies doesn’t change the unique’s values.

The Second Gotcha

You, a savvy developer, know all this although. You even have a extra superior information construction. You’ve got a record of lists.

[
    ['first element', 1, 2, 3],
    ['second element', 4, 5, 6],
    ['third element', 7, 8, 9],
]

Since you recognize about this gotcha, you will make a brand new object and duplicate the values to the brand new object.

>>> deeplist1 = [
...     ['first element', 1, 2, 3],
...     ['second element', 4, 5, 6],
...     ['third element', 7, 8, 9],
... ]
>>> deeplist2 = deeplist1.copy()
>>> print(f"deeplist1 id: {id(deeplist1)}")
deeplist1 id: 1497534571008
>>> print(f"deeplist2 id: {id(deeplist2)}")
deeplist2 id: 1497534577536

Now, with two completely different objects, is it protected to change a component in one of many sublists? Seems, it’s not.

>>> deeplist2[0][0] = "NOT 3RD"
>>> deeplist2
[['NOT 3RD', 1, 2, 3], ['second element', 4, 5, 6], ['third element', 7, 8, 9]]
>>> deeplist1
[['NOT 3RD', 1, 2, 3], ['second element', 4, 5, 6], ['third element', 7, 8, 9]]

However why? The ids of deeplist1 and deeplist2 are completely different. That is true, however the sublists usually are not. Every sublist is assigned the identical object id as the unique.

>>> id(deeplist1[0][0]), id(deeplist2[0][0])
(1497534796864, 1497534796864)

The Second Resolution

Make the most of the deepcopy() methodology to make a replica of your unique object.

>>> import copy
>>> deeplist3 = copy.deepcopy(deeplist1)
>>> deeplist3[0][0] = "NEW VALUE"
>>> deeplist3
[['NEW VALUE', 1, 2, 3], ['second element', 4, 5, 6], ['third element', 7, 8, 9]]
>>> deeplist1
[['NOT 3RD', 1, 2, 3], ['second element', 4, 5, 6], ['third element', 7, 8, 9]]

Utilizing deepcopy() we will safely make a replica of our record of lists and modify each the unique and the copy with out impacting the opposite.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles