5

list オブジェクトと islice オブジェクトはどちらも iterable ですが、なぜこの違いが生じるのでしょうか。

r = [1, 2, 3, 4]               
i1, i2 = tee(r)
print [e for e in r if e < 3]
print [e for e in i2]
#[1, 2]
#[1, 2, 3, 4]


r = islice(count(), 1, 5)          
i1, i2 = tee(r)
print [e for e in r if e < 3]
print [e for e in i2]
#[1, 2]
#[]
4

2 に答える 2

14

ここでの問題はtee()、元のイテレータから値を消費する必要があることです。元のイテレータから値を消費し始めると、正しく機能できなくなります。リストの例では、反復は単純に再開されます。ジェネレーターの例では、それは使い果たされ、それ以上の値は生成されません。

これは十分に文書化されています:

tee()が分割されたら、元のiterableを他の場所で使用しないでください。そうしないと、ティーオブジェクトに通知されなくてもイテラブルが進む可能性があります。

ソース

リストとジェネレーターの違いのポイントを説明するために編集します。

>>> from itertools import islice, count
>>> a = list(range(5))
>>> b = islice(count(), 0, 5)
>>> a
[0, 1, 2, 3, 4]
>>> b
<itertools.islice object at 0x7fabc95d0fc8>
>>> for item in a:
...     print(item)
... 
0
1
2
3
4
>>> for item in a:
...     print(item)
... 
0
1
2
3
4
>>> for item in b:
...     print(item)
... 
0
1
2
3
4
>>> for item in b:
...     print(item)
... 
>>> 
于 2012-06-12T14:47:00.487 に答える
0

リスト内包表記で、 に置き換えrますi1

于 2012-06-12T15:23:51.923 に答える