Hello everyone,
I struggle with a python code. I found the problem and reproduced the condition of its occurence in the following lines:
def PLS(A):
B = A
B[0] = B[2]
return(B)
A = [1,2,3]
D = PLS(A)
print(A)
Compiling those few lines, I expect
D
to be
[2,3,2]
and
A
to be
[1,2,3]
.
Yet I get
D = A = [2,3,2]
Why does the code modify the A list?
And how can I stop it from doing so?
I'm really thankful for any help, I've been stuck for a while on that :D
It would help us if you could use code tags (select code lines and click the blue/yellow python icon).
Your issue is that lists are assigned by reference so the line B = A means both B and A will point to the same memory location. If you want them to stay independent you can use the list slice notation:
def PLS(A):
B = A[:] # Taking a slice with no indexes grabs the whole list but makes an actual copy.
B[0] = B[2]
return(B)
Hey Liquid,
I am not sure why this error is happening but you can fix it by redefining A:
def PLS(A):
B = A
B[0] = B[2]
return(B)
A = [1,2,3]
D = PLS(A)
A = [1,2,3]
print(A)
This does not make a copy of the list, it makes two variables that both point to the same list.
a = [1, 2, 3]
b = a
print(id(b), id(a))
Output:
2504484054272 2504484054272
You can tell the two are the same list because both point to the same Python object (2504484054272)
If you want your PLS function to return a modified copy of the provided list, you first need to make a copy. In the code below I do this using
[:]
which makes a new list with the same contents as the original list.
def PLS(A):
B = A[:]
B[0] = B[2]
return(B)
A = [1,2,3]
D = PLS(A)
A = [1,2,3]
print(A, D)
print(id(A), id(D))
Output:
[1, 2, 3] [3, 2, 3]
1820201877184 1820196404928
The result is now what you want, and you can see from the object ID that you have two different lists
Another way to make a copy of a list is use copy.
import copy
def PLS(A):
B = copy.copy(A)
B[0] = B[2]
return(B)
(Aug-07-2020, 09:03 PM)deanhystad Wrote: [ -> ]This does not make a copy of the list, it makes two variables that both point to the same list.
a = [1, 2, 3]
b = a
print(id(b), id(a))
Output:
2504484054272 2504484054272
You can tell the two are the same list because both point to the same Python object (2504484054272)
If you want your PLS function to return a modified copy of the provided list, you first need to make a copy. In the code below I do this using [:]
which makes a new list with the same contents as the original list.
def PLS(A):
B = A[:]
B[0] = B[2]
return(B)
A = [1,2,3]
D = PLS(A)
A = [1,2,3]
print(A, D)
print(id(A), id(D))
Output:
[1, 2, 3] [3, 2, 3]
1820201877184 1820196404928
The result is now what you want, and you can see from the object ID that you have two different lists
Another way to make a copy of a list is use copy.
import copy
def PLS(A):
B = copy.copy(A)
B[0] = B[2]
return(B)
Aahh! Thank you a lot. That's different from languages I'm used to. I naively thought using a different variable name would lead to the duplication of the data set.
Damn, I have 1k lines of code waiting to be changed now :D
Thank you for your kind help!
In Python a variable is really nothing more than a name used to reference something, an entry in the namespace. I guess you could say that about all languages, but in Python there is no compiler preventing us from reusing the same variable to refer to different things. This is perfectly valid Python but would give C conniptions:
def myfunc(a):
return a
myvar = myfunc
myvar = myvar(1234)
myvar = str(myvar)
myvar = [int(c) for c in myvar]
Do you have any thoughts on my Machine Learning problem?