Python: Changes to My Copy Variable Affect the Original Variable

python: changes to my copy variable affect the original variable

That is because in python setting a variable actually sets a reference to the variable. Almost every person learning python encounters this at some point. The solution is simply to copy the list:

copy_list = org_list[:] 

Copied variable changes the original?

The line

aux=matriz;

Does not make a copy of matriz, it merely creates a new reference to matriz named aux. You probably want

aux=matriz[:]

Which will make a copy, assuming matriz is a simple data structure. If it is more complex, you should probably use copy.deepcopy

aux = copy.deepcopy(matriz)

As an aside, you don't need semi-colons after each statement, python doesn't use them as EOL markers.

changes to my duplicate variable modify the original variable

[:] or copy doesn't copy the list inside the outer list

So you're changing the same object, but you can use deepcopy to fix that, or simple copy the list inside:

from copy import deepcopy

puzzle = [[1, 2, 3]]
test_puzzle = deepcopy(puzzle)
# or
# test_puzzle = [x[:] for x in test_puzzle]
test_puzzle[0][1] = 7
print(puzzle)
print(test_puzzle)

will result in

[[1, 2, 3]]
[[1, 7, 3]]

Why does the original list change when I change the copied list (PYTHON)

you should use copy.deepcopy.

If your list is a list of integers or floats, copy would suffice but since you have list of lists, you need to recursively copy the elements inside the lists.

You can find more detailed answer here: What is the difference between shallow copy, deepcopy and normal assignment operation?

Elements of list deleted when deleting from a copy of the list

You need to change

tmp = music_list

to

tmp = music_list[:]

setting tmp to music list without copying, making a change to one will edit both lists.

This is assuming you don't want to edit music_list

The reason of this is because without copying you are referencing the same item in memory:

Without copying:

tmp = music_list

Memory locations:

>>> id(music_list)   
2614314102592
>>> id(tmp)
2614314102592

With copying:

tmp = music_list[:]

Memory locations:

>>> id(music_list)
1782888775808
>>> id(tmp)
1782888775744

How to avoid mutating original global variable when creating copy

The crux of your issue here is new_abacus = empty_abacus, which doesn't perform how you think it would. empty_abacus is passed by reference, which means that both new_abacus and empty_abacus will point to the same position in memory. Changes to one of the two will affect the same space in memory.

Instead, make a copy of empty_abacus within new_abacus:

import copy

# ... other code here ...

new_abacus = copy.deepcopy(empty_abacus)

Elements of the original list changes when a deep copy of changes

I think you need a quick reminder on shallow and deep copies, and how to make a deep copy.

>>> a = [[1,2], [3,4]] # a list of mutable elements
>>> b = a[:]
>>> c = list(a)

Both b and c are shallow copies of a, you can check that a, b and c are different objects because they do not share the same id.

>>> id(a)
140714873892592
>>> id(b)
140714810215672
>>> id(c)
140714873954744

However, each element of a, b and c still is a reference to the lists [1,2] and [3,4] we created when defining a. That becomes clear when we mutate an item inside the lists:

>>> c[1][1] = 42
>>> a
[[1, 2], [3, 42]]
>>> b
[[1, 2], [3, 42]]
>>> c
[[1, 2], [3, 42]]

As you can see, the second element of the second list changed in a, b and c.
Now, to make a deep copy of a, you have several options. One is a list comprehension where you copy each of the sublists:

>>> d = [sublist[:] for sublist in a]
>>> d
[[1, 2], [3, 42]]
>>> d[1][1] = 23
>>> d
[[1, 2], [3, 23]]
>>> a
[[1, 2], [3, 42]]

As you can see, the 42 in a did not change to 23, because the second list in a and d are different objects:

>>> id(a[1])
140714873800968
>>> id(d[1])
140714810230904

Another way to create a deep copy is with copy.deepcopy:

>>> from copy import deepcopy
>>> e = deepcopy(a)
>>> e
[[1, 2], [3, 42]]
>>> e[1][1] = 777
>>> e
[[1, 2], [3, 777]]
>>> a
[[1, 2], [3, 42]]


Related Topics



Leave a reply



Submit