ساخت ایتریتور به سبک ساده با generator
جنراتور تابعی است که بهجای return از کلیدواژهی yield استفاده میکند. هر بار که yield اجرا شود، مقدار برگردانده میشود اما وضعیت تابع (متغیرها و محل اجرا) حفظ میشود تا فراخوانی بعدی از همانجا ادامه یابد.
def count_up(limit):
current = 1
while current <= limit:
yield current
current += 1
for number in count_up(5):
print(number) # 1 2 3 4 5مزیت بزرگ جنراتورها، محاسبهی تنبل (lazy evaluation) است؛ یعنی مقادیر فقط در لحظهی نیاز تولید میشوند، نه همهباهم از قبل. این ویژگی برای کار با دادههای بسیار بزرگ یا حتی بینهایت، صرفهجویی زیادی در مصرف حافظه ایجاد میکند:
def infinite_numbers():
n = 1
while True:
yield n
n += 1
gen = infinite_numbers()
print(next(gen)) # 1
print(next(gen)) # 2همچنین عبارت جنراتوری (generator expression) نسخهی فشردهی list comprehension است که بهجای براکت از پرانتز استفاده میکند و نتیجه را بهصورت تنبل تولید میکند: (n * n for n in range(1000000)). برخلاف list comprehension، این عبارت تمام مقادیر را همزمان در حافظه نگه نمیدارد.