Reputation: 20862
folks, i got a question about passing mutable object to a function
with the following code, I was expecting the output to be [0,0,0], while the output is [0,1,2,3]
does it mean the argument is actually copied and then send to the inside of the function?
def lala(a):
n = [0, 0 , 0]
a = n
a = [0,1,2,3]
lala(a)
print a
if i want to fulfill the above task inside the function, how shall i write it elegantly?
thanks very much!
Upvotes: 0
Views: 680
Reputation: 184081
Python makes more sense if you think of attaching name tags to objects, rather than stuffing objects into named boxes.
def lala(a):
n = [0, 0 , 0]
a = n
Here's what's happening.
a
.n
.n
the additional name a
.a
and n
, are local to the lala
function, so they "expire" when the function ends.In other words, a
is not a box into which you can put a new list. It is a name you gave a list you received. Later, you reassign that name to the list you have also named n
.
Others have suggested a slice assignment, a[:] = n
, which uses a reference to the items in the list rather than the list itself. When you do this, the name a
still points to the same list; its contents have just been replaced. Since it is the same list that was passed into the function, any names by which it is known outside the function will "see" the new contents.
Upvotes: 8
Reputation: 5870
kindall provided a great explanation in my opinion, but my preferred method for doing something like this is to have the function return the change instead of messing with references.
def lala():
n = [0, 0, 0]
return n
a = [0, 1, 2, 3]
a = lala()
print a # prints [0, 0, 0]
Upvotes: 3
Reputation: 156138
python does not have a call-by-reference feature. There's no general way to do this.
If you know your argument is going to be a list, and you want it to take a different value, you can write it like so:
def lala(a):
a[:] = [0,0,0]
Upvotes: 2
Reputation: 304127
you can use a[:] = n
inside the function. this is called a slice assignment
Upvotes: 2
Reputation: 2594
That's because a function makes new label "a" for its scope. Then this "a" overshadows the "a" you defined outside the function. So the new label a is assigned to new object [0,0,0,0] If you would write:
def lala(a):
a.pop()
a = [0,1,2,3,4]
lala(a)
print(a)
You would see that a = [0,1,2,3] because pop() actually change the object which label 'a' points to. (while assignment just change to what object given label points to)
Upvotes: 1
Reputation: 61024
Note the difference between your function, and this one:
def lala(a):
a[0] = 7
a = [0,1,2,3]
lala(a)
print a # prints [7, 1, 2, 3]
Upvotes: 0