Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do Python for loops work by reference?

Tags:

python

When using a for loop in Python to iterate over items in a list, will changing item (below) change the corresponding item in items?

for item in items:     item += 1 

Will each item in items be incremented or remain the same as before the loop?

[Note: I would be interested in Python 2.7 and 3.x]

like image 799
James Avatar asked Feb 11 '13 15:02

James


People also ask

Does Python work with references?

Python always uses pass-by-reference values. There isn't any exception. Any variable assignment means copying the reference value.

How does a for loop work in Python?

for loops are used when you have a block of code which you want to repeat a fixed number of times. The for-loop is always used in combination with an iterable object, like a list or a range. The Python for statement iterates over the members of a sequence in order, executing the block each time.

Are for loops inclusive or exclusive?

For loops are always inclusive in Python: they always run over all elements of the iterator (other than exceptions such as break , etc.).

Is Python by reference or copy?

Long story short: Python uses pass-by-value, but the things that are passed by value are references. The actual objects have 0 to infinity references pointing at them, and for purposes of mutating that object, it doesn't matter who you are and how you got a reference to the object.


2 Answers

No, variables in Python are not pointers.

They refer to objects on a heap instead, and assigning to a variable doesn't change the referenced object, but the variable. Variables and objects are like labels tied to balloons; assignment reties the label to a different balloon instead.

See this previous answer of mine to explore that idea of balloons and labels a bit more.

That said, some object types implement specific in-place addition behaviour. If the object is mutable (the balloon itself can change), then an in-place add could be interpreted as a mutation instead of an assignment.

So, for integers, item += 1 is really the same as item = item + 1 because integers are immutable. You have to create a new integer object and tie the item label to that new object.

Lists on the other hand, are mutable and lst += [other, items] is implemented as a lst.__iadd__([other, items]) and that changes the lst balloon itself. An assignment still takes place, but it is a reassigment of the same object, as the .__iadd__() method simply returns self instead of a new object. We end up re-tying the label to the same balloon.

The loop simply gives you a reference to the next item in the list on each iteration. It does not let you change the original list itself (that's just another set of balloon labels); instead it gives you a new label to each of the items contained.

like image 138
Martijn Pieters Avatar answered Oct 12 '22 23:10

Martijn Pieters


Well, it really depends on the items.

Take the following case:

class test():     pass  a = test() a.value = 1  b = test() b.value = 2  l = [a,b]  for item in l:     item.value += 1  for item in l:     print item.value  >>>  2 3 

and in this case:

l2 = [1,2,3]  for item in l2:     item += 1  for item in l2:     print item  >>>  1 2 3 

So as you can see, you need to understand the pointers as Martijn said.

like image 23
Inbar Rose Avatar answered Oct 12 '22 22:10

Inbar Rose