
It is no doubt that the Python built-in module, Itertools, is quite powerful. Indeed, almost no one can use one article to introduce it inside-out. Therefore, I have picked up three iterator functions that help us yield an INFINITE number of elements. Of course, the pattern is defined by ourselves.
- Count
- Cycle
- Repeat
I’ll demonstrate these functions, as well as the typical scenarios that we could use them. With these examples, you will have a better idea of what they are designed for. If you have more creative ways of using them, please don’t be hesitate to let me know!
Let’s import them before any demos.
from itertools import count, cycle, repeat
1. Itertools.count()

Everyone can count. If we are not told to stop, theoretically we can count forever. In the Python world, it is very common to use the range()
function to generate a sequence of numbers. However, we have to let the function know that at which point it needs to stop.
But not for the count()
function. We don’t need to tell it when to stop, just keep getting next, next and next of it.
iter_count = count(0)
for i in range(10):
print(next(iter_count))

In the above example, we defined an iterator using the count()
function. We tell it should start from 0, but no need to tell when to stop. Then, we use the next()
function to get the value from it. Loop it 10 times, 10 numbers are generated by the iterator.
The count()
function also accepts the second parameter for customised step. The default step will be 1 if not specified.
iter_count = count(0.5, 0.5)
for i in range (10):
print(next(iter_count))

So, every time we get the next number, 0.5 will be added rather than 1.
Example 1: Get even and odd numbers
We can easily use the count()
function to generate an Arithmetic sequence. For example, we can use it to generate a list of odd or even numbers.
iter_count_odd = count(1, 2)
iter_count_even = count(0, 2)
odds = [next(iter_count_odd) for _ in range(10)]
evens = [next(iter_count_even) for _ in range(10)]
print(odds)
print(evens)

Example 2: Use count with the zip function
Suppose we have a list of students. Now, we want to automatically assign student ID to them. The student ID should start from 150000. We can use the count()
function to do this very conveniently.
Let’s generate a dummy list of student names first.
students = ['Alice', 'Bob', 'Chris', 'David', 'Eva']
Then, let’s generate the student IDs.
for i in zip(count(150001), students):
print(i)

Here, the most important thing is that we don’t have to know how many students we have. Also, we can easily convert the result into a dictionary if necessary.
2. Itertools.cycle

The second infinite iterator factory is the cycle()
function. Unlike the count()
function that will keep counting towards one direction, the cycle()
function will repeat a pattern over and over again.
iter_cycle = cycle(['a', 'b', 'c'])
for i in range(10):
print(next(iter_cycle))

In the above example, the list we passed in has 3 elements. The iterator generated by the cycle()
function will populate them one by one in order. When all the elements were used, it goes back to the beginning to get the first one again. Keep cycling 🙂
Example 3: Use cycle to generate Daily Rotated Roster
Suppose you’re in a team that people will be rotated to be on-call for one day. We need to generate a roster to be fair. Please be noticed that random might not be fair enough. Also, it is possible that someone will be on-call for more than one day in a row, which is definitely something we need to avoid.
In this case, the cycle()
function will help. But before that, let’s generate a list of dates first.
from datetime import datetime, timedelta
dates = [(datetime(2021, 1, 1) + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(10)]

Now, we can use the zip()
function with the cycle iterator to generate the roster.
iter_cycle = cycle(['Alice', 'Bob', 'Chris'])
for i in zip(dates, iter_cycle):
print(i)

If we have one year to generate, don’t worry, just use cycle()
because it is infinite.
3. Itertools.repeat

If we want to repeat something forever or for certain times, the repeat()
function is always the best choice in Python. Firstly, let’s generate an infinite iterator that repeatedly gives us the same thing.
iter_repeat = repeat('Towards Data Science')
for i in range(10):
print(next(iter_repeat))

Please be noticed that the repeat()
function also takes an optional second parameter to become finite.
list(repeat('Towards Data Science', 5))

In the above example, we generated a list of the same string for 5 replicas.
Example 4: Faster than list
It is reasonable to ask why we need to the repeat()
function? For example, generating a list with 5 same string can be as easy as follows.
['Towards Data Science'] * 5

Indeed, in terms of readability, this is much better. However, the repeat iterator will cache the result, while the list multiplication will generate 5 distinct strings in memory.

We can see that the repeat iterator is roughly 4x faster in this case. If we need more than 5 times, the speed difference will be even larger.
Example 5: Faster Loop than range()
It is very common to use range()
when we want to loop something for certain times. For example, for i in range(10)
will loop 10 times.
However, when we don’t need that i
, which means that we don’t care about the looping rounds, the repeat iterator will be a better solution in terms of the performance.

We can see that using the repeat()
function is 2x faster than the range()
function. The former wins because all it needs to do is update the reference count for the existing None
object. The latter loses because the range()
or xrange()
needs to manufacture 10,000 distinct integer objects.
Summary

In this article, I’ve introduced 3 infinite iterators of the Itertools module of Python. By knowing them, sometimes it could improve our productivity to a large extent. However, I would also recommend balancing the readability and the performance. Don’t always use the code to show off and only use them when necessary.
If you are interested in more Python built-in modules, please check out these related articles.
If you feel my articles are helpful, please consider joining Medium Membership to support me and thousands of other writers! (Click the link above)