Numbering, round-robin assignment and constant streams are common, and they combine cleanly with zip and map.
Three iterators never stop on their own:
count(start=0, step=1)yieldsstart, start+step, ...forever. Steps can be floats or negative. It's likerangewithout an end.cycle(iterable)repeats the items of an iterable forever. It saves a copy of the items on the first pass, so it uses memory proportional to the input.repeat(obj, times=None)yields the same object forever, ortimestimes.
Because they're infinite, always pair them with something that stops: zip (stops at the shortest input), islice, takewhile, or a break. list(count()) never returns.
Typical uses:
zip(count(1), lines)numbers items (thoughenumerate(lines, 1)is clearer for that exact case).zip(tasks, cycle(workers))assigns tasks round-robin.map(pow, range(5), repeat(2))feeds a constant argument to a function.
repeat yields the same object every time. list(repeat([], 3)) gives three references to one list, just like [[]] * 3, so mutating one mutates all.
Floating-point steps in count accumulate error; for exact decimal steps, count integers and scale: (i / 10 for i in count()).
Example
from itertools import count, cycle, islice, repeat
for n, line in zip(count(1), ["alpha", "beta"]):
print(n, line)
# 1 alpha
# 2 beta
workers = cycle(["w1", "w2"])
print([(t, next(workers)) for t in "abc"]) # [('a', 'w1'), ('b', 'w2'), ('c', 'w1')]
print(list(islice(count(10, 5), 3))) # [10, 15, 20]
print(list(map(pow, range(4), repeat(2)))) # [0, 1, 4, 9]
grid = list(repeat([], 2))
grid[0].append("x")
print(grid) # [['x'], ['x']] -- same listRemember
count,cycleandrepeatare infinite unless limited- Stop them with zip, islice, takewhile or a break
repeatyields the same object each time
Watch out for
- Calling
list()orsorted()on an infinite iterator, which never returns.