The following script demonstrates the reuse of Python generator objects:
cat << EOF > tee_demo.py
import itertools
dat = ((x + 3) * 2 for x in range(10))
g1, g2, g3 = itertools.tee(dat, 3)
print(f'next(g1) = {next(g1)}')
print(f'next(g2) = {next(g2)}')
print(f'next(g3) = {next(g3)}')
print(f'next(g3) = {next(g3)}')
print(f'next(g3) = {next(g3)}')
print(f'next(g1) = {next(g1)}')
print(f'next(g2) = {next(g2)}')
print('g1 and g2 are consistent after g3 advancing')
print(f'next(g3) = {next(g3)}')
print(f'next(dat) = {next(dat)}')
print(f'next(dat) = {next(dat)}')
print(f'next(g3) = {next(g3)}')
print(f'next(g1) = {next(g3)}')
print(f'next(g2) = {next(g3)}')
print('g1,g2,g3 are unconsistent after dat advancing')
dat2 = ((x + 3) * 2 for x in range(10))
c1, c2, c3 = itertools.tee(dat2, 3)
print(f'next(c1) = {next(c1)}')
print(f'next(c2) = {next(c2)}')
print(f'next(c3) = {next(c3)}')
print(f'next(c1) = {next(c1)}')
print(f'next(c1) = {next(c1)}')
print(f'next(c1) = {next(c1)}')
print(f'next(c2) = {next(c2)}')
print(f'next(c3) = {next(c3)}')
print('c1,c2,c3 keep consistent when dat2 untouched')
EOF
$ python tee_demo.py
next(g1) = 6
next(g2) = 6
next(g3) = 6
next(g3) = 8
next(g3) = 10
next(g1) = 8
next(g2) = 8
g1 and g2 are consistent after g3 advancing
next(g3) = 12
next(dat) = 14
next(dat) = 16
next(g3) = 18
next(g1) = 20
next(g2) = 22
g1,g2,g3 are unconsistent after dat advancing
next(c1) = 6
next(c2) = 6
next(c3) = 6
next(c1) = 8
next(c1) = 10
next(c1) = 12
next(c2) = 8
next(c3) = 8
c1,c2,c3 keep consistent when dat2 untouched
It's also a good explanation of the following citation from the official documents of itertools.tee:
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.
For this example, the above sentence can be rewritten as:
Once tee()
has made a split, the original iterable dat
should not be used anywhere else;
otherwise, the iterable could get advanced without
the tee objects (g1, g2, g3
) being informed.
Note:
the fstring in print()
function is a new language feature in Python 3.6.