Объект, возвращенный range()
(или xrange()
в Python2.x) известен как generator.
Вместо хранения всего диапазона [0,1,2,..,9]
в памяти генератор хранит определение для (i=0; i<10; i+=1)
и вычисляет следующее значение только тогда, когда это необходимо (AKA ленивая оценка).
По существу, генератор позволяет возвращать список как структура, но вот некоторые отличия:
- Перечень хранит все элементы, при его создании. Генератор генерирует следующий элемент, когда это необходимо.
- Список может быть переработан как можно больше, генератор может быть повторен только по точно один раз.
- Список может получать элементы по индексу, генератор не может - он только генерирует значения один раз, от начала до конца.
Генератор может быть создан двумя способами:
(1) Очень похож на список понимания:
# this is a list, create all 5000000 x/2 values immediately, uses []
lis = [x/2 for x in range(5000000)]
# this is a generator, creates each x/2 value only when it is needed, uses()
gen = (x/2 for x in range(5000000))
(2) В качестве функции, используя yield
, чтобы вернуть следующее значение:
# this is also a generator, it will run until a yield occurs, and return that result.
# on the next call it picks up where it left off and continues until a yield occurs...
def divby2(n):
num = 0
while num < n:
yield num/2
num += 1
# same as (x/2 for x in range(5000000))
print divby2(5000000)
Примечание: Хотя range(5000000)
является генератором в Python3.x, [x/2 for x in range(5000000)]
все еще является списком. range(...)
выполняет свою работу и генерирует x
по одному, но весь список значений x/2
будет вычисляться при создании этого списка.
Создать генератор (например 'def', содержащий' yield'), который вызывает побочный эффект, такой как 'print', прежде чем он даст значение. Затем запустите генератор с односекундной задержкой на каждую итерацию. Когда происходят отпечатки? Python 3 'range' (так же, как' xrange' в Python 2) работает примерно так: вычисления не выполняются до тех пор, пока не будут заданы. Это то, что означает «ленивая оценка». – user2864740