Home > Software design >  Why is a variable automatically modified even though I am not modifying it?
Why is a variable automatically modified even though I am not modifying it?

Time:09-17

I simplified my code to get the error I required.

one = ['x']
two = ['y']
final_data = []
for r in range(1, 3):
    print(final_data, r)
    if r == 2:
        one[0] = two[0]
        print(one)
    final_data.append(one)
    print(final_data)
print(final_data)

The final data in 2nd loop is not modified but the end result is coming [['y'], ['y']] even though I expect it to come as [['x'], ['y']]

CodePudding user response:

In this line one[0] = two[0] you change the value in list one and in the end when you print final_data you get [['y'], ['y']] because in list one you have 'y'.

You need for each iteration to create a copy of one. To copy a list you can use [:]. Then after you do what you want with one, copy old_one to one.

...
old_one = one[:]
...
one = old_one[:]

Try this:

one = ['x']
two = ['y']
final_data = []
for r in range(1, 3):
    print(final_data, r)
    old_one = one[:]
    if r == 2:
        one[0] = two[0]
        print(one)
    final_data.append(one)
    one = old_one[:]
    print(final_data)
print(final_data)

CodePudding user response:

In short:

final_data.append( one )

does not add the contents of list one but a reference to the list called one to final_data.

In C / C terminology, a "pointer" (or "reference") to list one is added such that by the time r==2:

final_data = [ <reference to `one`>, <reference to `one`> ]

So by modifying one[0] to be one[0] = two[0], the contents of one are changed and consequently final_data will see those changes too.

Possibly a simpler solution is to:

import copy

...
final_data.append( copy.deepcopy(one) )

copy.deepcopy() generates - as the name implies - a full copy of the object, such that now a reference to a new list will be added to final_data in stead of (yet another) reference to the list called one.

  • Related