nos
nos

Reputation: 20862

python passing argument to a function

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

Answers (6)

kindall
kindall

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.

  1. You're receiving a parameter (a list in this case) and giving it the name a.
  2. You're creating a new list and giving it the name n.
  3. You are giving the list you named n the additional name a.
  4. Both names, a and n, are local to the lala function, so they "expire" when the function ends.
  5. The list you created in the function now has no names, and Python discards it.

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

arboc7
arboc7

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

SingleNegationElimination
SingleNegationElimination

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

John La Rooy
John La Rooy

Reputation: 304127

you can use a[:] = n inside the function. this is called a slice assignment

Upvotes: 2

Piotr Lopusiewicz
Piotr Lopusiewicz

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

Steve Tjoa
Steve Tjoa

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

Related Questions