ひとつのイテレータを複数の箇所で使いまわそうとしてまして。
>>> from itertools import count
>>> fooiter = count()
>>> tuple(zip(fooiter, ('a', 'b', 'c')))
((0, 'a'), (1, 'b'), (2, 'c'))
>>> tuple(zip(fooiter, ('a', 'b', 'c')))
((4, 'a'), (5, 'b'), (6, 'c'))
イテレータ (count()
) が 3 を飛ばす。
なぜなら第2引数のタプルの終端を検出する前に第1引数のイテレータを評価 (next()
)するから第1引数を最後に評価した値 3 (そして7も) は破棄されてしまう。
>>> tuple(zip(('a', 'b', 'c'), fooiter))
(('a', 0), ('b', 1), ('c', 2))
>>> tuple(zip(('a', 'b', 'c'), fooiter))
(('a', 3), ('b', 4), ('c', 5))
>>>
インデックスが後ろについて気持ち悪いがそれは気持ちの問題。
「イテラブルの左から右への評価順序は保証されています。」
ちょっと考えればすぐわかる話(←強調)。