Python : When is a variable passed by reference and when by value? [duplicate]

Why is loc not reference of elements of locs ? Python : Everything is passed as reference unless explicitly copied [ Is this not True ? ] Please explain.. how does python decides referencing and copying ? Update : How to do ?

def compute(ob): if isinstance(ob,list): return process_list(ob) if isinstance(ob,dict): return process_dict(ob) for loc in locs: loc = compute(loc) # What to change here to make loc a reference of actual locs iteration ? 
61.3k 13 13 gold badges 120 120 silver badges 166 166 bronze badges asked Mar 14, 2012 at 5:36 Yugal Jindle Yugal Jindle 45.3k 43 43 gold badges 134 134 silver badges 200 200 bronze badges Everything is passed by value, but every value is just a reference ;) Commented Mar 14, 2012 at 5:42

6 Answers 6

Effbot (aka Fredrik Lundh) has described Python's variable passing style as call-by-object: http://effbot.org/zone/call-by-object.htm

Objects are allocated on the heap and pointers to them can be passed around anywhere.

Hope that clarifies the issue for you.

133k 30 30 gold badges 235 235 silver badges 235 235 bronze badges answered Mar 14, 2012 at 7:08 Raymond Hettinger Raymond Hettinger 224k 65 65 gold badges 399 399 silver badges 498 498 bronze badges

Everything in Python is passed and assigned by value, in the same way that everything is passed and assigned by value in Java. Every value in Python is a reference (pointer) to an object. Objects cannot be values. Assignment always copies the value (which is a pointer); two such pointers can thus point to the same object. Objects are never copied unless you're doing something explicit to copy them.

For your case, every iteration of the loop assigns an element of the list into the variable loc . You then assign something else to the variable loc . All these values are pointers; you're assigning pointers; but you do not affect any objects in any way.

answered Mar 14, 2012 at 19:30 122k 29 29 gold badges 166 166 silver badges 225 225 bronze badges

In my point of view - You described it the best. Just tell me the answer of the Update to the question - that part you missed.

Commented Mar 15, 2012 at 5:40

So what happens with integer and float numbers then? Are they just considered immutable objects? How does python manage that as I'm sure it cannot hold all conceivable numbers in memory ready to be referenced.

Commented Apr 23, 2017 at 23:55

@AndrewS: Integers and floats are indeed immutable (it should be apparent that they do not have methods that mutate themselves). I am not sure what the second part of your comment means.

Commented Apr 28, 2017 at 20:20

@AndrewS: Maybe they are the same and maybe they aren't. Why does it matter? This has nothing to do with mutability or semantics of assignment.

Commented May 2, 2017 at 6:19

@AndrewS yes, float and int objects are. objects. And they are immutable. Everything in Python is an object. The behavior of the example you gave is implementation dependant, and could change given any python version, even in minor-version updates. But basically, the CPython compiler will often optimize immutable constant expressions to the same object. How and when it happens depends on a lot of things, and again, is an implementation detail

Commented Jul 22, 2020 at 8:13

It doesn't help in Python to think in terms of references or values. Neither is correct.

In Python, variables are just names. In your for loop, loc is just a name that points to the current element in the list. Doing loc = [] simply rebinds the name loc to a different list, leaving the original version alone.

But since in your example, each element is a list, you could actually mutate that element, and that would be reflected in the original list:

for loc in locs: loc[0] = loc[0] * 2 
answered Mar 14, 2012 at 5:42 Daniel Roseman Daniel Roseman 597k 68 68 gold badges 900 900 silver badges 914 914 bronze badges

It might be helpful to read Idiomatic Python - "other languages have variables, Python has labels." The rest of it is good reading too. ;)

Commented Mar 14, 2012 at 5:50 How to modify each element of the container ? \ Commented Mar 14, 2012 at 5:54 @Yugal which part of what I've written above was not clear? Commented Mar 14, 2012 at 5:56

Generally, I just want to process each element of my container. So, how can that be acheived ? If everything is a label that seems to be a disadvantage when actaully want to edit the element.

Commented Mar 14, 2012 at 5:58

@YugalJindle : To modify elements in a list, use the square brackets to reference items in that list.

Commented Mar 14, 2012 at 7:00

you are rebinding the loc variable to a newly created empty list

Perhaps you want

Which assigns a slice (which happens to be the whole list) of loc to the empty list

answered Mar 14, 2012 at 5:40 John La Rooy John La Rooy 302k 54 54 gold badges 375 375 silver badges 510 510 bronze badges I believe this last example is what OP was looking for ! Commented May 24, 2013 at 8:45

Everything is passed by object. Rebinding and mutating are different operations.

locs = [ [1], [2] ] for loc in locs: del loc[:] print locs 
answered Mar 14, 2012 at 5:39 Ignacio Vazquez-Abrams Ignacio Vazquez-Abrams 794k 158 158 gold badges 1.4k 1.4k silver badges 1.4k 1.4k bronze badges

Why is loc not reference of elements of locs ?

It is. Or at least, it is in the same sense that every other variable in Python is. Python variables are names, not storage. loc is a name that is used to refer to elements of [[1,2], [3,4]] , while locs is a name that refers to the entire structure.

This does not mean "look at the thing that loc names, and cause it to turn into [] ". It cannot mean that, because Python objects are not capable of such a thing.

Instead, it means "cause loc to stop being a name for the thing that it's currently a name for, and start instead being a name for [] ". (Of course, it means the specific [] that's provided there, since in general there may be several objects in memory that are the same.)

Naturally, the contents of locs are unchanged as a result.