Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python; modifying list inside a function

Tags:

python

list

Suppose I have function with list parameter, and inside its body I want to modify passed list, by copying elements of an array to the list:

def function1 (list_arg):
   a = function2()    #function2 returns an array of numbers
   list_arg = list(a)

list1 = [0] * 5
function1(list1)
list1
[0,0,0,0,0]

When doing it like this, it doesn't work. After executing function1(list1), list1 remains unchanged. So, how to make function1 return list1 with the same elements (numbers) as array a?

like image 200
roberto Avatar asked Feb 26 '14 22:02

roberto


People also ask

Can I modify list in function Python?

And while most of the data types we've worked with in introductory Python are immutable (including integers, floats, strings, Booleans, and tuples), lists and dictionaries are mutable. That means a global list or dictionary can be changed even when it's used inside of a function, just like we saw in the examples above.

Why do my lists get modified when passed to a function?

Because python parameter is passed by object reference, and list is a mutable object, once you pass a list into function and change its element, the original one would be change too.

Can list be mutated in Python?

It all depends on what you are actually doing, appending or any direct mutation of the list will be reflected outside the function as you are actually changing the original object/list passed in.

How to modify an item within a list in Python?

Run the code in Python, and you’ll get this list: You can modify an item within a list in Python by referring to the item’s index. What does it mean an “item’s index”?

How do I create a list in Python?

To start, create a list in Python. For demonstration purposes, the following list of names will be created: Run the code in Python, and you’ll get this list: You can modify an item within a list in Python by referring to the item’s index.

Are Python functions supposed to create new local variables?

I thought Python functions were supposed to create new local-only variables. Note: The original lists are not and cannot be immutable. Later I will modify them, but I will need the originals to do that.

How to change the value of list1 in func ()?

If you use the "list1" name to change the value of what is being referred to, rather than pointing the "list1" name within func () to something else, then that will be seen by the rest of the program. def func (list1): del list1 [0:2] # list1 = list1 [2:] # print (list1) # prints [2, 3] list1 = [0, 1, 2, 3] func (list1) print (list1)


Video Answer


4 Answers

If you assign something to the variable list_arg, it will from then on point to the new value. The value it pointed to before that assignment (your original list) will stay unchanged.

If you, instead, assign something to elements of that list, this will change the original list:

list_arg[:] = list(a)

This will make your code work as you wanted it.

But keep in mind that in-place changes are hard to understand and probably can confuse the next developer who has to maintain your code.

like image 71
Alfe Avatar answered Oct 07 '22 16:10

Alfe


What I think you are asking is why after calling f(a), when f re-assigns the a you passed, a is still the "old" a you passed.

The reason for this is how Python treats variables and pass them to functions. They are passed by reference, but the reference is passed by value (meaning that a copy is created). This means that the reference you have inside f is actually a copy of the reference you passed. This again implies that if you reassign the variable inside the function. It is a local variable existing only inside the function; re-assigning it won't change anything in outside scopes.

Now, if you rather than reassigning the local variable/reference inside f (which won't work, since it's a copy) perform mutable operations on it, such as append(), the list you pass will have changed after f is done.

See also the question How do I pass a variable by reference? which treats the problem and possible solutions in further detail.

TL;DR: Reassigning a variable inside a function won't change the variable you passed as an argument outside the function. Performing mutable operations on the variable, however, will change it.

like image 23
Håvard S Avatar answered Oct 07 '22 18:10

Håvard S


You can operate on the list to change its values (eg, append something to it, or set its values) but changes will be reflected outside of the function only if you operate on the reference to the passed in object:

def function1 (list_arg):
   list_arg.append(5)

If you have questions when doing this, print out the ids:

def function1 (list_arg):
   print 1, id(list_arg)
   list_arg[:] = ["a", "b", "c"]
   print 2, id(list_arg)
   list_arg = range(10)
   print 3, id(list_arg)

x = [1,2,3]
function1(x)
print x

prints:

1 4348413856
2 4348413856
3 4348411984
['a', 'b', 'c']

That is, x is changed in place, but assigning to the function's local variable list_arg has no impact on x, because is then just assigns a different object to list_arg.

like image 8
tom10 Avatar answered Oct 07 '22 18:10

tom10


You're changing a reference to a local variable. When you pass in list_arg this way:

def function1 (list_arg):

list_arg is a reference to an underlying list object. When you do this:

   list_arg = list(a)

You're changing what list_arg means within the function. Since the function exits right after that, list_arg = list(a) has no effect.

If you want to actually change the reference to the list you have to do assign it to the result of the function.

def function1 ():
   'a = some array'
   return list(a)

list1 = [0] * 5
list1 = function1()

Or you could modify the contents of the list without changing the reference.

def function1(list_arg):
    del list_arg[:]  # Clears the array
    'a = some array'
    list_arg.extend(a)
like image 2
Geoff Genz Avatar answered Oct 07 '22 17:10

Geoff Genz