Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a list iterator in Python not allowed?

Simple example:

myList = [1, 2, 3, 4, 5]
for obj in myList:
  obj += 1
print myList

prints

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

while:

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
  myList[index] += 1
print myList

prints

[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]

Conclusion:

  1. Lists can be modified in place using global list access Lists can
  2. List items can NOT be modified in place using the iterator object

All example code I can find uses the global list accessors to modify the list inplace. Is it so evil to modify a list iterator?

like image 713
RobW Avatar asked Feb 23 '12 13:02

RobW


2 Answers

The reason obj += 1 does not do what you expect is that this statement does not modify obj in-place. Instead, it computes the new value, and rebinds the variable obj to point to the new value. This means that the contents of the list remain unchanged.

In general it is possible to modify the list while iterating over it using for obj in myList. For example:

myList = [[1], [2], [3], [4], [5]]
for obj in myList:
  obj[0] += 1
print(myList)

This prints out:

[[2], [3], [4], [5], [6]]

The difference between this and your first example is that here, the list contains mutable objects, and the code modifies those objects in-place.

Note that one could also write the loop using a list comprehension:

myList = [val+1 for val in myList]
like image 159
NPE Avatar answered Nov 05 '22 03:11

NPE


in for obj in myList:, in every iteration, obj is a (shallow) copy of the element in myList. So the change on the obj does nothing to myList's elements.

It's different with the Perl for my $obj (@myList) {}

like image 38
Ade YU Avatar answered Nov 05 '22 03:11

Ade YU