Xiidref
Xiidref

Reputation: 1531

Python weird iterator behaviour

I was on another SO question here : Query on [Python sum of number in array, ignoring sections of specific numbers]

In this question, there was a code similar to this :

it = iter([4, 5, 6, 7, 8, 9])
print([x for x in it if x!=4 not in it]) #Output [5]

To my understanding, an iterator is like a list in which we remove each element after accessing them. I also get that making an operation like not in will loop over the iterator until it find the value it's searching for. So in the case where we do 3 not in iter([1, 2]) the iterator will be empty since the not in have looped over all of it to confirm that 3 wasn't included.

So in my understanding, the first iteration of the for loop should do the following :

it = iter([4, 5, 6, 7, 8, 9])
for x in it:
    #Here it look like [5, 6, 7, 8, 9] and x is 4
    if x!=4 not in it:
        # So here we've done 
        #x!=4 => False 
        #then False not in it
        #Since False isn't in it the iterator should now be empty and we don't enter this if
        print(x)

#And there is'nt a second iteration since the iterator is empty dues to the if condition so
#the loop should end after the first iteration without anything printed

But this code output is 5 how on earth is this possible ???
So if someone can explain in details what is happening exactly it would be greatly appreciated !

Side notes :
I've also tried with

Which make me wonder how is this condition interpreted by python, since none of the parenthesized versions match the version without parenthesis.

Upvotes: 2

Views: 76

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96350

So, the problem here is the expression:

x != 4 not in it

Is implicitly chained, because that is how comparison operators work

So that means it is evaluated as:

(x != 4) and (4 not in it)

Since x != 4 is False on the first iteration, it short circuits and goes on to the next iteration without evaluating 4 in it. In which case, x == 5, and it doesn't short circuit and it exhausts the iterator checking if 5 not in it, in which case, the whole expression is True and it is the only item in the resulting list.

Upvotes: 4

Related Questions