Я изучал модуль Python itertools
и наткнулся на функцию itertools.product
, которая возвращает то же самое, что и ((x,y) for x in A for y in B)
. Я считаю, что это действительно аккуратный способ сокращения вложенности в сложных for-loops
, где понимание списка может быть неадекватным. Однако, прежде чем продолжить, я хотел проверить, как это работает с альтернативными методами. Вот несколько тестов, которые я провел. Использовал встроенный в Jupyter Notebook %%timeit
для измерения производительности.
case-1: понимание ванильного списка
%%timeit -n 50 -r 5
[(x,y) for x in range(1000) if x%2==0 for y in range(1000) if y%2==1]
>>> 35.8 ms ± 1.3 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)
case-2: itertools.product в понимании списка
Удален itertools
импорт, чтобы избежать показа здесь времени импорта.
%%timeit -n 50 -r 5
[(x,y) for (x,y) in itertools.product(range(1000), range(1000)) if x%2==0 and y%2==1]
>>> 62.1 ms ± 1.16 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)
case-3: ваниль, вложенная в l oop
%%timeit -n 50 -r 5
lst = []
for x in range(1000):
for y in range(1000):
if x%2 == 0 and y%2 == 1:
lst.append((x,y))
>>> 72 ms ± 769 µs per loop (mean ± std. dev. of 5 runs, 50 loops each)
case-4: для l oop с itertools.product
%%timeit -n 50 -r 5
lst = []
for x, y in itertools.product(range(1000),range(1000)):
if x%2==0 and y%2==1:
lst.append((x,y))
>>> 74.5 ms ± 2.13 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)
Однако эта часть документации, как я полагаю, требует лучшей производительности, чем ваниль for
петли. Кроме того, case-2 не должен быть быстрее, чем case-1 ? В case-3 и case-4 разница в производительности ухудшается для itertools.product
при увеличении размеров итерируемых элементов. Что здесь происходит? Кроме того, добавьте несколько примеров, где itertools.product
может быть лучшим кандидатом, чем listcomp, или вложенным в циклы.