Вдохновленный моим собственным ответом, я даже не понял, как он работает сам, рассмотрим следующее:
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