2

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
  • The general idea is to not update the collection you are iterating over in a loop. btw there are no iterators in your code samples. Commented Nov 9, 2020 at 9:37
  • 3
    The for loop gets an iterator once of num at the beginning of the loop, which then looks at each value in the list one by one. num = ... replaces the variable num with a different list, but that's of no interest to the for loop, because it doesn't look at num again after it has already gotten its iterator. Commented Nov 9, 2020 at 9:39
  • 2
    Your first example mutates the list; your second example creates a new list and assigns it to num while you continue to iterate over the original list. Commented Nov 9, 2020 at 9:43

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

Glad it helped. If you are interested in learning more about the topic, search about mutable vs immutable objects in Python ;)
0

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]

2 Comments

Yes, but I wanted to know why the "i" did not update as the previous one.
Explained in the answer also. It's actually mutated in the first instance of lopp itself. So 5 is printed in the 3rd loop instance.
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.