Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tee function from itertools library

Both list and islice objects are iterable but why this difference in result.

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]
#[]
like image 567
John Avatar asked Jun 12 '12 14:06

John


1 Answers

The issue here is that tee() needs to consume the values from the original iterator, if you start consuming them from the original iterator, it will be unable to function correctly. In your list example, the iteration simply begins again. In the generator example, it is exhausted and no more values are produced.

This is well documented:

Once tee() has made a split, the original iterable should not be used anywhere else; otherwise, the iterable could get advanced without the tee objects being informed.

Source

Edit to illustrate the point in the difference between a list and a generator:

>>> 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)
... 
>>> 
like image 91
Gareth Latty Avatar answered Oct 04 '22 06:10

Gareth Latty