Friday, August 2, 2019

Looping N Times

The itertools module is one of my favorite modules in the Python standard library!

Here's an interesting example.

Often we just want to repeat an operation n times, and we don't particularly care about the loop counter.

The common approach is to use range to do this.

For example, to repeat something 10 times, we can write:

for _ in range(10):
    print('python')

(Here I use the underscore (_) character to indicate I don't care about the loop counter - but _ is a valid variable name, so nothing special going on here)

This works fine, but we have to create a range object, and we can in fact approach this more efficiently using the itertools module.

The function itertools.repeat(obj, n) will basically create a generator that will yield the specified obj, n times.

For example:

import itertools

for s in itertools.repeat('python', 5):
    print(s)

Now in the original intent we don't actually care about the loop counter, so we can use None as the object:

for _ in itertools.repeat(None, 5):
    print('python')

Using itertools.repeat actually offers us better performance.

Let's time some operations where we want to find the maximum value of a sequence of N random numbers.

from itertools import repeat
from timeit import timeit
import random

def find_max_range(n):
    random.seed(0)
    return max(random.random() for _ in range(n))

def find_max_iter(n):
    random.seed(0)
    return max(random.random() for _ in repeat(None, n))

 print(timeit('find_max_range(10_000)', 
              globals=globals(), number=1_000))
 print(timeit('find_max_iter(10_000)', 
              globals=globals(), number=1_000))

 When I run this, I get the following timings:

  •  using range: 1.09s
  •  using repeat: 0.93s

 So using repeat is about 14% faster than using range!

1 comment:

Looping N Times

The itertools  module is one of my favorite modules in the Python standard library! Here's an interesting example. Often we just wan...