2

I am a newbie to python so just a simple question about how python functions work since I am accustomed to C/C++ so here is my problem that I have a list:

a = ['0','1','2','3','4','5','6','7','8','9']

and I have a function which takes two elements of list and swap them:

def swap(d,e):
    temp = e
    e = d
    d = temp

now when I pass it arguments like suppose

swap(a[0],a[5])

it doesn't do anything I mean list remains unaltered.Also I have defined my function at the very begining of the py file so also when I insert print temp like

def swap(d,e):
    temp = e
    print temp
    e = d
    d = temp

it gives me correct value say what a[5] is I mean if I have done anything like this in C

starrify
  • 14,307
  • 5
  • 33
  • 50
saurabh
  • 293
  • 2
  • 7
  • 19
  • 2
    Shouldn't be surprising for you, coming from C/C++. Imagine that you write the exact same thing in C, making `a` a `char *`, and `void swap(char d, char e)`. Would you expect a change? – Ricardo Cárdenes Feb 22 '14 at 11:57
  • This wouldn't have worked in C or C++, either (though C++ would have let you declare the arguments as references, which would have worked). – user2357112 Feb 22 '14 at 11:57
  • You might wanna read: [How do I write a function with output parameters (call by reference)?](http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference) – Ashwini Chaudhary Feb 22 '14 at 11:57
  • Since you are used to C: think of *every* variable as a pointer to the actual object. You might also be interested in [this](http://stackoverflow.com/q/21390975/510937) question about `import`s, since they are *not* the same as C's `include`. – Bakuriu Feb 22 '14 at 12:13

2 Answers2

3

When you assign temp to e, you're just creating a new reference to the object e, but what you take, has nothing to do with the list.

def swap(l, o, n): #pass the list, old position, new position
    l[n], l[o] = l[o], l[n]

This way, you do change the list.

aIKid
  • 26,968
  • 4
  • 39
  • 65
  • I have assigned e as a[5] so anything I perform on e must reflect on a[5] so what is exactly happening – saurabh Feb 22 '14 at 11:57
  • @saurabh Umm.. Not exactly like that. As jonrsharpe mentioned, they are bound _locally_ to `d` and `e`. When you assigned `e` to `a[5]`, you created a _new_ reference. Thus, changing `a[5]` _will_ change the value of `e`, but not the inverse. Reassigning `e` will only make it point to another object. AFAIK, it's not exactly like that in C either. – aIKid Feb 22 '14 at 12:02
  • 1
    @saurabh: you're familiar with C. So let's say you write `char *a = "hello"; char *d = &a[0]; char *e = &a[5]; char *tmp = d; d = e; e = tmp;`. Would you say, "I have assigned `e` as `a[5]`, so anything I perform on `e` must reflect on `a[5]`"? If you would say that, then you are mistaken about C :-) Python variables are references to objects, they are not the referenced object. – Steve Jessop Feb 22 '14 at 12:04
  • @alKid I might have mistaken something but your answer and explaination does helps. – saurabh Feb 22 '14 at 12:10
1

When you pass the objects from the list to swap, they are bound locally to the argument names d and e. You then swap d with e but that doesn't change the list. You could return the values:

def swap(d, e):
    return e, d

Then call it like:

a[0], a[5] = swap(a[0], a[5])

But clearly you might as well just do:

a[0], a[5] = a[5], a[0]

Alternatively, pass the list and indices, per alKid's answer.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437