Хорошо, поэтому я попытался прочитать несколько источников: One, Two, Three. Первый источник ясно указывает, что использование выражений генератора сохраняет память и ускоряет работу. Но что происходит, когда они становятся вложенными? Вот пример, и я надеюсь, что кто-то сможет помочь мне понять это.Является ли гнездование генераторов в Python лучше?
In [1]: def nested():
[(ix, '-'.join(str(x) for x in hours)) for ix in table.index.get_level_values(0)]
%timeit nested
Out [1]: 10000000 loops, best of 3: 33.5 ns per loop
In [2]: def not_nested():
hr = '-'.join(str(x) for x in hours) #hr = 7-8
[(ix, hr) for ix in table.index.get_level_values(0)]
%timeit not_nested
Out [2]: 10000000 loops, best of 3: 38.7 ns per loop
В приведенном выше примере, hours
список 2 элементов длиной, в то время как количество индексов в table
на уровне 0 равно 32.
Если бы я был запустить две функции в моей голове, я предположил бы, что в функции nested
вторая половина кортежа ('-'.join(str(x) for x in hours
) будет вызываться столько раз, сколько выполняется цикл «внешний» (ix
) (то есть столько раз, сколько есть индексов в table
). Однако в функции not_nested
вторая половина кортежа инициализируется один раз (сохраняется в hr
) и не будет запускаться каждый раз, когда выполняется вторая строка.
Во-первых, правильно ли я думаю, что так работает Python? Если я тогда, то кто-нибудь может объяснить, как время выполнения вложенной функции меньше, чем одно не вложенное?
Begin Редактировать/Решение
Видимо, я сделал ошибку в вызове функции, как два ответа просветить. Я снова побежал timeit
с вызовом правильной функции, и получил ожидаемые результаты:
In [1]: %timeit nested()
Out [1]: 10000 loops, best of 3: 55.5 µs per loop
In [2]: %timeit not_nested()
Out [2]: 100000 loops, best of 3: 4.53 µs per loop
В конечном счете, делая среду выполнения, когда не вложена часть от выполнения при вложенной. Спасибо всем за ответ и очищение!
End Edit
Вы правы. Я только что протестировал его, и для вложенной функции требуется больше времени (используются фиктивные данные). Покажите нам правильный тест (со всеми данными), или это неверно. :) – freakish
Nope, @freakish. Это была ошибка, которую я сделал, поскольку ответы ниже просветлены. – Kartik