3

Suppose I have this function

>>>a=3
>>>def num(a):
       a=5
       return a
>>>num(a)
5
>>>a
3

Value of a doesnt change.

Now consider this code :

>>> index = [1]
>>> def change(a):
       a.append(2)
       return a
>>> change(index)
>>> index
>>> [1,2] 

In this code the value of index changes. Could somebody please explain what is happening in these two codes. As per first code, the value of index shouldnt change(ie should remain index=[1]).

3

4 Answers 4

7

You need to understand how python names work. There is a good explanation here, and you can click here for an animation of your case.

If you actually want to operate on a separate list in your function, you need to make a new one, for instance by using

a = a[:]

before anything else. Note that this will only make a new list, but the elements will still be the same.

Sign up to request clarification or add additional context in comments.

5 Comments

Hmm those would help I guess. going through them . Thanks
Another question is , that suppose I dont want my index to change even after a call to change(index). How would I edit my function change(a) to work in that case. [ Basically I want change(a) to behave exactly like num(a) ]. Is it possible ?
prepend a.append(2) with a = a.copy(). This will create a new list with contents of your index and assign it to a. This will create a shallow copy of index - all elements that were inside index are shared between index and a so if index[0] is a dictionary, doing a[0]['test'] = 1 would be visible in index[0]. If you want to deep copy the list, see deepcopy
Sorry, i've meant list(a).
@vinita what does work is b=copy(a) (it changes the type of a but oh well). I do recommend looking at deepcopy and a function: id("thingie").
1

The value of index doesn't change. index still points to the same object it did before. However, the state of the object index points to has changed. That's just how mutable state works.

7 Comments

So you mean to say that if index=[1] resides at address 3456 in memory ,then after function call it will still reside at(or begin at) address 3456, but with an extra element at address 3457. Am I right now ?
@vinita No, you’re looking at a too low level, and your low-level description is too simple – the Python list object (and other objects) are more complex than that, but the low-level details are not important here. The relevant point is that the value that index refers to doesn’t change. The content of that value changes but not the value itself.
@vinita, speaking of pointers, think of the num function as void* num(void* a). Explanation using C (not necessarily fully accurate): a = 3 creates a void* a = &(int object of 3). Now calling num(a) causes the function to receive a copied pointer to int object of 3, not a reference to the pointer.
Im sorry but Im getting confused here :-( The last two scentences are difficult to imagine
This specific case of call-by-value, where the value is a pointer to a (mutable) object is also sometimes called call-by-oject-sharing, call-by-sharing or call-by-object. Note: this is not call-by-reference!
|
1

Line 3 in the first block of code is assignment and in the second block is mutation, and that's why you are observing that behavior.

3 Comments

Hmm that kind of makes some sense to me now. So I can only mutate a global variable via a function call, but not assign it a new value.
You can assign it a new value by using global a statement before changing it's value. Also make sure that there is no other variable named a in the scope you are using global a.
@vinita nope you are get it wrong. you can mutate any (global) variable only if it allows you to do so. The global variable in your first block of code is an integer which is immutable where as in the second block it's a list which can mutated via append, extend, etc attributes of an object of type list.
0

The issue you are encountering is:

a = 3
def num(a):
    # `a` is a reference to the argument passed, here 3.
    a = 5
    # Changed the reference to point at 5, and return the reference.
    return a

num(a)

The a in the num function is a diffrent object than the a defined globally. It works in case of the list because a points at the list passed, and you modify the object being referenced to by the variable, not the reference variable itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.