Python itertools库中的tee函数

Python itertools库中的tee函数,python,itertools,Python,Itertools,list和islice对象都是可编辑的,但为什么会出现这种结果上的差异呢 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] p

list和islice对象都是可编辑的,但为什么会出现这种结果上的差异呢

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]
#[]
r=[1,2,3,4]
i1,i2=三通(r)
打印[如果e<3,则e代表r中的e]
打印[e代表i2中的e]
#[1, 2]
#[1, 2, 3, 4]
r=islice(count(),1,5)
i1,i2=三通(r)
打印[如果e<3,则e代表r中的e]
打印[e代表i2中的e]
#[1, 2]
#[]

这里的问题是
tee()
需要使用原始迭代器中的值,如果您开始使用原始迭代器中的值,它将无法正常工作。在列表示例中,迭代只是再次开始。在生成器示例中,它已耗尽,不再生成值

这是有据可查的:

一旦tee()进行了拆分,原始iterable就不应在其他任何地方使用;否则,iterable可能会在不通知tee对象的情况下得到提升

编辑以说明列表和生成器之间的区别:

>>> 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)
... 
>>> 
>>从itertools导入islice,计数
>>>a=列表(范围(5))
>>>b=islice(count(),0,5)
>>>a
[0, 1, 2, 3, 4]
>>>b
>>>对于a中的项目:
...     打印(项目)
... 
0
1.
2.
3.
4.
>>>对于a中的项目:
...     打印(项目)
... 
0
1.
2.
3.
4.
>>>对于b项:
...     打印(项目)
... 
0
1.
2.
3.
4.
>>>对于b项:
...     打印(项目)
... 
>>> 

在列表理解中,您希望用
i1
替换
r
,但列表对象和islice对象的行为需要类似,对吗?@John No,当您循环列表时,每次都会得到一个新的迭代器,这意味着您仍然可以得到值。当您使用
islice()
时,您将得到一个生成器,该生成器将生成一次值,然后耗尽。你自己试试看-只需在列表上循环两次,然后取一个islice并循环两次-注意行为上的差异。@John要使这两个示例的行为相似,请使用
r=iter([1,2,3,4])
而不是
r=[1,2,3,4]
。如果你从tee中销毁迭代器,你能提升原始迭代器吗?