Да, генераторы и genexprs обычно (хе) медленнее, чем списки, но, с другой стороны, они лениво оцениваются, и вам не нужно платить за память за полностью предварительно вычисленный список.Я полагаю, что разница в скорости вызвана служебной информацией кадра вызова с (неявным или явным) yield
перебрасыванием значений вокруг.
Использование вашего кода, но timeit
для его измерения, и с третьей версией, использующейФункция генератора:
import timeit
def f1():
x = []
for j in [i**2 for i in range(20000)]:
x.append(j)
return x
def f2():
x = []
for j in (i**2 for i in range(20000)):
x.append(j)
return x
def f3():
def gen():
for i in range(20000):
yield i ** 2
x = []
for j in gen():
x.append(j)
return x
print(timeit.timeit(f1, number=100))
print(timeit.timeit(f2, number=100))
print(timeit.timeit(f3, number=100))
Результаты (Python 3.7.0) указывают на то, что genexprs работает точно так же быстро, как функции генератора, примерно на 4-5% медленнее, чем понимание списка.
f1 = 2.882695159
f2 = 3.0303254170000002
f3 = 3.002670741