Posts: 2
Threads: 1
Joined: Aug 2020
Aug-07-2020, 08:14 PM
(This post was last modified: Aug-07-2020, 09:52 PM by Yoriz.)
Hello everyone,
I struggle with a python code. I found the problem and reproduced the condition of its occurence in the following lines:
1 2 3 4 5 6 7 8 |
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
Posts: 99
Threads: 1
Joined: Dec 2019
Aug-07-2020, 08:31 PM
(This post was last modified: Aug-07-2020, 08:42 PM by Marbelous.)
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:
1 2 3 4 |
def PLS(A):
B = A[:]
B[ 0 ] = B[ 2 ]
return (B)
|
"So, brave knights, if you do doubt your courage or your strength, come no further, for death awaits you all with nasty, big, pointy teeth!" - Tim the Enchanter
Posts: 10
Threads: 4
Joined: Aug 2020
Hey Liquid,
I am not sure why this error is happening but you can fix it by redefining A:
1 2 3 4 5 6 7 8 9 |
def PLS(A):
B = A
B[ 0 ] = B[ 2 ]
return (B)
A = [ 1 , 2 , 3 ]
D = PLS(A)
A = [ 1 , 2 , 3 ]
print (A)
|
Posts: 6,818
Threads: 20
Joined: Feb 2020
Aug-07-2020, 09:03 PM
(This post was last modified: Aug-07-2020, 09:03 PM by deanhystad.)
This does not make a copy of the list, it makes two variables that both point to the same list.
1 2 3 |
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.
1 2 3 4 5 6 7 8 9 10 |
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.
1 2 3 4 5 6 |
import copy
def PLS(A):
B = copy.copy(A)
B[ 0 ] = B[ 2 ]
return (B)
|
Posts: 2
Threads: 1
Joined: Aug 2020
Aug-07-2020, 09:47 PM
(This post was last modified: Aug-07-2020, 09:47 PM by Liquid.)
(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.
1 2 3 |
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.
1 2 3 4 5 6 7 8 9 10 |
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.
1 2 3 4 5 6 |
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!
Posts: 6,818
Threads: 20
Joined: Feb 2020
Aug-07-2020, 11:06 PM
(This post was last modified: Aug-07-2020, 11:08 PM by deanhystad.)
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:
1 2 3 4 5 6 |
def myfunc(a):
return a
myvar = myfunc
myvar = myvar( 1234 )
myvar = str (myvar)
myvar = [ int (c) for c in myvar]
|
Posts: 10
Threads: 4
Joined: Aug 2020
Do you have any thoughts on my Machine Learning problem?
|