Why hasn't this list changed? [duplicate] - python

This question already has answers here:
Python functions call by reference [duplicate]
(12 answers)
Closed 3 years ago.
In the following code, the function modify_list want to modify b, but it failed, the print result is [1,2,3]. why hasn't the list a changed?
def modify_list(b):
b = [1,2]
a = [1,2,3]
modify_list(a)
print(a)

If you want something like this to work you can do:
def modify_list(b):
return [1,2]
a = [1,2,3]
a = modify_list(a)
print(a)
Or
def modify_list(b):
b[:] = [1,2]
a = [1,2,3]
modify_list(a)
print(a)

you are declaring other local variable b, if you want to mutate you can do:
b[:] = [1, 2]
or even better you can return your desired value for list a
if you want to change your list a value you can assign the desired value:
a = [1, 2]

Related

Function don't update the list realtime python [duplicate]

This question already has answers here:
Appending to a list comprehension in Python returns None
(3 answers)
Closed 2 years ago.
def func(a,b):
a=a.append(b)
if a is not None:
for i in a:
print(i)
li=[1,2,3]
def testcall():
c=10
func(li,c)
if __name__=='__main__':
test()
Why it is not printing the updated list
even though is I update the list in test function and then sent it, it'll not print anything. Does anyone have any clue why the function is having this strange behavior.
If I let the "func" to only accept the one argument and sent update the list in "test" It'll still don't show anything.
To answer your main concern of "why doesn't it print anything", when you perform a = a.append(b), the inner a.append(b) returns nothing, so a is nothing. Also, a major issue exists with your code because it lacks correct indentation and you've misnamed your call to testcall() as test(). This is probably what you want.
def func(a,b):
print(a) # [1,2,3]
a.append(b)
print(a) # [1,2,3,10]
if a is not None:
for i in a:
print(i)
li=[1,2,3]
def testcall():
c=10
func(li,c)
if __name__=='__main__':
testcall()
Some experiments you can do from within IDLE:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = a.append(b)
>>> c
>>> a
[1, 2, 3, [4, 5, 6]]
>>>

How to copy a list over in python without keeping them linked? [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 5 years ago.
I tried:
A = [1,2,3]
B = A
B[0] = A[0]*3
should give:
B == [3,2,3]
True
A == [1,2,3]
True
but what it really does:
B == [3,2,3]
A == [3,2,3]
how do I copy A over in B without keeping A linked to B?
Thanks for your help.
This is because you are only pointing the reference to B, without making a copy at all. Instead do the following to actually create a copy.
A = [1,2,3]
B = A[:]
This will work if there are no referenced variables. If you don't want that behaviour, then use a deep_copy method as below
B = copy.deepcopy(A)
Then if you change A, it won't change B

Variable name as function argument? [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 6 years ago.
I wish to make a function whose arguments are the name of a list L, and its arguments. The list L has just numbers in it, and I want to round them all to 1 decimal(by the way, the elements of the list L should be replaced by the rounded numbers, I don't want a new list M with them). Sadly, the list name varies in the script I'm planning, and so does the length of such lists. Here is my failed attempt:
def rounding(name,*args):
M=[round(i,1) for i in args] #here is the list I want L to become
name=M #here I try to replace the previous list with the new one
morada=[1,2.2342,4.32423,6.1231] #an easy example
rounding(morada,*morada)
print morada
Output:
[1, 2.2342, 4.32423, 6.1231] #No changes
Have the rounding function return a value.
def rounding(list_):
return [round(i, 1) for i in list_]
Then you can do this:
>>> morada=[1,2.2342,4.32423,6.1231] #an easy example
>>> morada = rounding(morada)
>>> morada
[1, 2.2, 4.3, 6.1]
Or if you really really wanted it to assign within the function you could do this:
def rounding(list_):
list_[:] = [round(i,1) for i in args]
Close. Lists are mutable, so...
name[:] = M
You can use eval()
For example, the following will start with a list containing [1, 2, 3, 4] and change the first element to 5:
list_0 = [1, 2, 3, 4]
def modify_list(arg):
list_1 = eval(arg)
list_1[0] = 5
modify_list('list_0')
print list_0

Copy a list of list by value and not reference [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Copying nested lists in Python
(3 answers)
Closed 4 years ago.
To understand why I was getting an error in a program , in which I tried to find the "minor" of a determinant, I wrote a simpler program because my variables were messed up. This function below takes in a 2 * 2 matrix as an input, and returns a list containing its rows (pointless and inefficient, I know, but I'm trying to understand the theory behind this).
def alpha(A): #where A will be a 2 * 2 matrix
B = A #the only purpose of B is to store the initial value of A, to retrieve it later
mylist = []
for i in range(2):
for j in range(2):
del A[i][j]
array.append(A)
A = B
return mylist
However, here it seems that B is assigned the value of A dynamically, in the sense that I'm not able to store the initial value of A in B to use it later. Why is that?
Because python passes lists by reference
This means that when you write "b=a" you're saying that a and b are the same object, and that when you change b you change also a, and viceversa
A way to copy a list by value:
new_list = old_list[:]
If the list contains objects and you want to copy them as well, use generic copy.deepcopy():
import copy
new_list = copy.deepcopy(old_list)
Since Python passes list by reference, A and B are the same objects. When you modify B you are also modifying A. This behavior can be demonstrated in a simple example:
>>> A = [1, 2, 3]
>>> def change(l):
... b = l
... b.append(4)
...
>>> A
[1, 2, 3]
>>> change(A)
>>> A
[1, 2, 3, 4]
>>>
If you need a copy of A use slice notation:
B = A[:]
A looks like a reference type, not a value type. Reference types are not copied on assignment (unlike e.g. R). You can use copy.copy to make a deep copy of an element

Understanding Python variables assignment [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 9 years ago.
If I execute this code:
a = [1,2,3]
b = a
b.remove(2)
print(a,b)
What I expect to see is:
[1,2,3] [1,3]
But this is what I really get:
[1,3] [1,3]
Why calling b.remove(2) also affects a?
What if I want to change b,while keeping a copy of the original content in a?
When you do b = a, you simply create another reference to the same list. So any modifications to that list will affect both a and b. So doing b.remove(2) will affect the single list that you have.
If you want to get your expected results, you can create a copy of the list:
b = a[:]
This way, you create a copy of the list, and you can modify one without changing the other.
>>> a = [1,2,3]
>>> b = a[:]
>>> b.remove(2)
>>> print a,b
[1, 2, 3] [1, 3]
a and b are two names for the same list, so if you change the list through one name, you can see the changes through the other name. If you want them to be different lists, make a copy:
b = a[:]
or
b = list(a)

Categories