Вдохновленный моим собственным ответом, я даже не понял, как он работает сам, рассмотрим следующее:
def has22(nums):
it = iter(nums)
return any(x == 2 == next(it) for x in it)
>>> has22([2, 1, 2])
False
Я ожидал, что a StopIteration будет поднято, так как при достижении 2, next(it) будет продвигать потребленный итератор. Однако кажется, что это поведение полностью отключено, только для генераторных выражений! Выражение генератора кажется сразу break после этого.
>>> it = iter([2, 1, 2]); any(x == 2 == next(it) for x in it)
False
>>> it = iter([2, 1, 2]); any([x == 2 == next(it) for x in it])
Traceback (most recent call last):
File "<pyshell#114>", line 1, in <module>
it = iter([2, 1, 2]); any([x == 2 == next(it) for x in it])
StopIteration
>>> def F(nums):
it = iter(nums)
for x in it:
if x == 2 == next(it): return True
>>> F([2, 1, 2])
Traceback (most recent call last):
File "<pyshell#117>", line 1, in <module>
F([2, 1, 2])
File "<pyshell#116>", line 4, in F
if x == 2 == next(it): return True
StopIteration
Даже это работает!
>>> it=iter([2, 1, 2]); list((next(it), next(it), next(it), next(it))for x in it)
[]
Итак, я думаю, мой вопрос в том, почему это поведение включено для выражений генератора?
Примечание: То же поведение в 3.x