Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

about iterators in python [duplicate]

If I have the following list:

a = [1, 2, 3]

And I run the following code:

for x in a:
  x += 1

It seems that this does not change the list a.

However, if I do the following:

for i in range(0, len(a)):
  a[i] += 1

This will modify the content of 'a'.

So I guess x and a[i] are referring to elements of a in a different way. What exactly is causing the difference? How are they each referring to elements of a?

like image 986
Enzo Avatar asked Dec 20 '22 07:12

Enzo


1 Answers

When you iterate over a list, each element is yielded, in turn. However, there are different kinds of objects. mutable and immutable. When you do something like:

a += 1

with an immutable object, it translates roughly to:

a = a + 1

Now in this case, you take the object reference by a, add 1 to it to create a new object. Then you assign that new object the name a. Notice how if we do this while iterating, we don't touch the list at all -- We only keep creating new objects and assigning them to the name a.

This is different for a mutable object. Then a += 1 actually changes the object in place. So, the list will see the change because the object that it is holding has changed (mutated). (With the immutable object the object contained in the list wasn't changed because it couldn't be). See this question for more info.

This also makes it a little more clear what's happening when you're iterating by indices. you construct a new integer and you put it in the list (forgetting whatever was in that slot before).

like image 113
mgilson Avatar answered Jan 30 '23 13:01

mgilson