Strange behavior observed when iterating over list in python

Viewed 80

I has a small question, Let me share a small snippet of code

num = [1, 2, 3, 4]

for i in num:
    print(i)
    num[2] = 5

here the output is

1
2
5
4

the iterator's value got updated to 5 instead of 3 in the 3rd iteration, now if I do this

num = [1, 2, 3, 4]

for i in num:
    print(i)
    num = [5 if j == 3 else j for j in num]

the output is

1
2
3
4

the iterator stayed the same this the 3rd iteration Does anyone know the reason for this behavior? (I observed this in Python 3.8 or 2.7)

3 Answers

When you run the for loop, it takes the id of the provided object and iterates over it.

In the first code snippet, you are changing an element of the original object, so when the iterator reaches the second element it takes the updated value.

However, in the second case you are creating a new object with different values, but the object that you provided to the loop stays the same.

A way of checking this behaviour is to get the id of the variable before and after the modifications, and see how it does not change in the first case but it changes in the second case:

my_list = [1, 2, 3]
original_id = id(my_list)

# Check if the object identification changes after modifying one element
my_list[2] = 4
new_id = id(my_list)
if original_id == new_id:
   print("1st case: The ID stays the same")
else:
   print("1st case: The ID has changed")

# Check now what happens if you create a new list
my_list = [3, 2, 1]
new_id = id(my_list)
if original_id == new_id:
   print("2nd case: The ID stays the same")
else:
   print("2nd case: The ID has changed")

The obtained result is the following:

1st case: The ID stays the same
2nd case: The ID has changed

In your first code, your num[2]=5 replaces values in first loop instance itself, so 5 is printed in the normal loop.

Your second code:

It's actually replacing and only i is printed in second code.

You need to print num to check the replaced value.

Code:

num = [1, 2, 3, 4]

for i in num:
    print(i)
    num = [5 if j==3 else j for j in num ]
    
print (num)# This line

Output:

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

The for loop already gets an iterator of num, and while inside loop you modify num, then the for loop does not look again to num, and iterates using the old list.

Related