-1

I've found out that while executing for loop over list of mutable items I cannot modify that item, however I am able to modify element of that item if that element is mutable. Why?

# Create alist which contain mutable
alist = [[1, 2, 3],]

#1 For loop
for x in alist:
    x = x + [9,]
print alist
# let's replace alist[0] to list which contain another one and try to modify it
alist[0] = [[[1,2],3]]

print2 alist # [[[[1, 2], 3]]]
#2 For loop
for x in alist:
    x[0] = x[0] + [9,]
# list modified ...
print alist # [[[[1, 2], 3, 9]]], Modified !

I am aware that modifying list which you are iterating on isn't good practice (it's better to iterate over copy of it), so please don't point me to that moment.

Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82

1 Answers1

0

The reason of such behaviour is that while performing for loop #1 new list is produced by applying + operator to list( it can be tracked by getting id of x).

However in for loop #2 by access element of item with index x[0] object which already in memory is being modified. It can be easily found by calling id on x while iterating over alist

# Create alist which contain mutable
alist = [[1, 2, 3],]

#1 for loop
for x in alist:
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0]) 
    # id(x): 4425690360 id(alist[0]) 4425690360 Same?: True
    x = x + [9,]
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0]) 
    # id(x): 4425770696 id(alist[0]) 4425690360 Same?: False
# mutable item not modified, so my guess is that x actually are copy of that item
print alist # [[1, 2, 3]]
# let's replace alist[0] to list which contain another one and try to modify it
alist[0] = [[[1,2],3]]

print alist
#2 for loop
for x in alist:
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0]) 
    # id(x): 4425811008 id(alist[0]) 4425811008 Same?: True

    x[0] = x[0] + [9,]
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0])
    # id(x): 4425811008 id(alist[0]) 4425811008 Same?: True
# list modified ...
print alist # [[[[1, 2], 3, 9]]]

To solve problem use array.append to modify item within for loop, see sample below:

alist = [[1, 2, 3],]
for x in alist:
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0])
    x.append(9)
    print id(x), id(alist[0]), 'Same?:', id(x) == id(alist[0])
# list modified ...
print alist # [[1, 2, 3, 9],]
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82