Infinite Iterators in Python: itertools.count, cycle, repeat

Modified: | Tags: Python

In Python, the itertools.count(), itertools.cycle(), and itertools.repeat() functions in the standard library's itertools module can be used to create infinite iterators.

For each function, examples of the iterative process using the for statement and combinations with the zip() function are presented. When using them in a for statement, ensure you specify an end condition and use break; otherwise, the code will result in an infinite loop.

See the following articles for more information about the for statement and the zip() function.

Infinite loops, such as those with counters, can be implemented using the while statement, but itertools functions often provide a simpler solution.

Count infinitely: itertools.count()

itertools.count() creates an iterator that counts up or down infinitely.

By default, it starts at 0 and increases by 1.

import itertools

for i in itertools.count():
    print(i)
    if i > 3:
        break
# 0
# 1
# 2
# 3
# 4

You can specify the starting value with the first argument start, and the increment with the second argument step.

for i in itertools.count(2):
    print(i)
    if i > 3:
        break
# 2
# 3
# 4

for i in itertools.count(step=3):
    print(i)
    if i > 8:
        break
# 0
# 3
# 6
# 9

for i in itertools.count(2, 3):
    print(i)
    if i > 8:
        break
# 2
# 5
# 8
# 11

To count down, specify a negative value for step.

for i in itertools.count(10, -1):
    print(i)
    if i < 8:
        break
# 10
# 9
# 8
# 7

You can use a floating-point number (float) for step, but using multiplication may be more accurate in some cases.

When counting with floating point numbers, better accuracy can sometimes be achieved by substituting multiplicative code such as: (start + step * i for i in count()). itertools.count() — Functions creating iterators for efficient looping — Python 3.11.3 documentation

for i in itertools.count(0.1, 1.5):
    print(i)
    if i > 3:
        break
# 0.1
# 1.6
# 3.1

for i in itertools.count():
    ii = 0.1 + 1.5 * i
    print(ii)
    if ii > 3:
        break
# 0.1
# 1.6
# 3.1

By combining it with zip(), you can create tuples that include a counter.

l1 = ['a', 'b', 'c']
l2 = ['x', 'y', 'z']

print(list(zip(itertools.count(), l1, l2)))
# [(0, 'a', 'x'), (1, 'b', 'y'), (2, 'c', 'z')]

Note that using enumerate() and zip() together creates nested tuples.

print(list(enumerate(zip(l1, l2))))
# [(0, ('a', 'x')), (1, ('b', 'y')), (2, ('c', 'z'))]

When used in a for loop, you can also extract each value using enumerate() and zip() as follows.

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for i, (name, age) in enumerate(zip(names, ages)):
    print(i, name, age)
# 0 Alice 24
# 1 Bob 50
# 2 Charlie 18

Cycle elements of an iterable infinitely: itertools.cycle()

itertools.cycle() creates an iterator that cycles through the elements of an iterable object, such as a list, infinitely.

l = [1, 10, 100]

sum_value = 0

for i in itertools.cycle(l):
    print(i)
    sum_value += i
    if sum_value > 300:
        break
# 1
# 10
# 100
# 1
# 10
# 100
# 1
# 10
# 100

Example of specifying range():

sum_value = 0

for i in itertools.cycle(range(3)):
    print(i)
    sum_value += i
    if sum_value > 5:
        break
# 0
# 1
# 2
# 0
# 1
# 2

Example of combining with zip():

l1 = [1, 10, 100]
l2 = [0, 1, 2, 3, 4, 5, 6]

print(list(zip(itertools.cycle(l1), l2)))
# [(1, 0), (10, 1), (100, 2), (1, 3), (10, 4), (100, 5), (1, 6)]

itertools.cycle() saves a copy of the original iterable object. Note that if the original iterable object is large, it may consume a significant amount of memory.

Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable). itertools.cycle() — Functions creating iterators for efficient looping — Python 3.11.3 documentation

Repeat the same value infinitely: itertools.repeat()

itertools.repeat() creates an iterator that returns the same value infinitely.

sum_value = 0

for i in itertools.repeat(10):
    print(i)
    sum_value += i
    if sum_value > 40:
        break
# 10
# 10
# 10
# 10
# 10

Specify the number of iterations using the second argument times.

for i in itertools.repeat(10, 3):
    print(i)
# 10
# 10
# 10

The first argument can be any object, including a function object. In the following example, the built-in len() function is repeated.

for l in itertools.repeat([0, 1, 2], 3):
    print(l)
# [0, 1, 2]
# [0, 1, 2]
# [0, 1, 2]

for func in itertools.repeat(len, 3):
    print(func('abc'))
# 3
# 3
# 3

The following example demonstrates combining with zip() to add constant elements.

l = [0, 1, 2, 3]

print(list(zip(itertools.repeat(10), l)))
# [(10, 0), (10, 1), (10, 2), (10, 3)]

Related Categories

Related Articles