فصل سوم: جنراتورها و ایتریتورها

جنراتورها و کلیدواژه‌ی yield

ساخت ایتریتور به سبک ساده با 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، این عبارت تمام مقادیر را همزمان در حافظه نگه نمی‌دارد.

برای ذخیره‌ی پیشرفت و شرکت در آزمون، وارد شوید — رایگان است.