Search code examples
pythonperformanceloopspython-itertools

Difference between itertools.product and loops


Is it better to use:

for i, j in itertools.product(range(3), range(3)):
    #code here

Or:

for i in range(3):
    for j in range(3):
        #code here

Sourcery.ai refactor recommends changing nested loops with range() to itertools.product(). Does it have better performance?


Solution

  • It can be useful to use itertools.product if you want to avoid nesting for loops, or if you want to generate the cartesian product of some iterables. In that case, itertools.product could improve readability of code over nested for loops.

    There is no practical advantage to using itertools.product over a nested for loop with range anymore with respect to memory consumption. A range in Python 3 uses constant memory, regardless of the size of the range it represents. It only needs to store the start, stop, and step values, and it generates the values needed to iterate over the loop lazily.

    As far as runtime performance, I did a simple test, and the nested for loop using range seems to be faster than itertools.product in a tight loop:

    >>> def loop():
    ...   for i in range(1000):
    ...     for j in range(1000):
    ...       pass
    ... 
    >>> timeit.timeit(loop, number=300)
    2.2965646009997727
    >>> def itertools_product():
    ...   for i, j in itertools.product(range(1000), range(1000)):
    ...     pass
    ...
    >>> timeit.timeit(itertools_product, number=300)
    2.8750368439996237