در پایتون، جنریتور یک تایپ خاص از iterable است، شبیه به یک لیست یا یک تاپل، اما با چند تفاوت کلیدی. برخلاف لیست ها یا تاپل ها، جنریتورها محتویات خود را در رم ذخیره نمی کنند. درعوض، آنها مقدار ها را همانطور که درخواست می شود، تولید میکنند.
جنریتور تایپی iterable است که به جای اینکه همه مقادیر را به یکباره در رم ذخیره کند، دنباله ای از مقادیر را تولید می کند. این می تواند برای کار با توالی های بزرگ یا نامتناهی از داده ها مفید باشد، زیرا به شما امکان می دهد به جای اینکه سعی کنید همه چیز را همزمان در رم بارگذاری کنید، با یک مقدار در یک زمان کار کنید.
جنریتورها هنگام برخورد با مجموعه داده های بزرگ یا توالی های نامحدود مفید هستند، جایی که تولید همه مقادیر به یکباره و ذخیره آنها در رم غیرعملی یا غیرممکن است. جنریتورها با تولید مقادیری که در لحظه نیاز دارند، به ما این امکان را میدهند که با این مجموعه دادهها به طور موثر و بدون تمام شدن حافظه کار کنیم.
دلایل مختلفی وجود دارد که ممکن است بخواهید از یک جنریتور در پایتون استفاده کنید:
به طور کلی، جنریتورها میتوانند ابزار قدرتمندی برای کار با توالیهای بزرگ، پیچیده یا نامتناهی از دادهها به روشی انعطافپذیر، کارآمد و سازگار با رم باشند.
مثال:
در این کد یک تابع جنریتور به نام ()fibonacci تعریف شده است که دنباله فیبوناچی را به طور نامحدود تولید می کند. کلمه کلیدی yield برای به دست آوردن هر مقدار در دنباله ای که تولید می شود استفاده می شود.
سپس تابع جنریتور فراخوانی شده و به متغیر gen نسبت داده می شود. یک آبجکت جنریتور ایجاد می کند که می تواند برای تولید دنباله فیبوناچی استفاده شود.
در نهایت تابع print() با آرگومان آبجکت gen فراخوانی می شود. با این حال، این عملا دنباله فیبوناچی را چاپ نمی کند. در عوض، نمایش رشتهای از آبجکت جنریتور را چاپ میکند، که چیزی شبیه <generator object fibonacci at 0x7ff6137ea5e0> خواهد بود.
برای تولید دنباله فیبوناچی، میتوانید از آبجکت جنریتور برای تکرار روی دنباله استفاده کنید و هر مقدار را در لحظه تولید کنید، برای مثال:
این کد 10 عدد اول را در دنباله فیبوناچی ایجاد می کند: 0، 1، 1، 2، 3، 5، 8، 13، 21، 34.
توجه داشته باشید که تابع next() برای بازیابی مقدار بعدی در دنباله هر بار از طریق حلقه استفاده می شود.
روش بعدی:
شش فراخوانی ()next در این کد وجود دارد، بنابراین شش عدد اول در دنباله فیبوناچی تولید و در ترمینال چاپ خواهند شد.
آبجکت جنریتور gen وضعیت فعلی تابع فیبوناچی را ردیابی می کند، بنابراین هر فراخوانی بعدی از جایی که تماس قبلی متوقف شده است ادامه می یابد.
از طرف دیگر، میتوانید از تابع itertools.islice() برای بدست آوردن slice ای از دنباله استفاده کنید:
استفاده از itertools.islice() یک راه راحت برای بدست آوردن slice ای از یک آبجکت جنریتور بی نهایت بدون نیاز به تولید کل دنباله است. تنها با تولید آیتم های مورد نیاز خود، می توانید در رم و زمان پردازش صرفه جویی کنید، به خصوص هنگام کار با توالی های بزرگ یا بی نهایت.
تابع جنریتور دنباله فیبوناچی را به طور نامحدود تولید می کند. هر بار که جنریتور فراخوانی می شود، مقدار بعدی را در دنباله تولید می کند.
توجه داشته باشید که از آنجایی که تابع فیبوناچی یک جنریتور است، در واقع کل دنباله اعداد فیبوناچی را به یکباره تولید نمی کند. درعوض، هر عدد را همانطور که درخواست میشود، تولید میکند، که باعث میشود نسبت به تکنیکهای دیگر برای تولید دنبالههای بزرگ اعداد، از نظر حافظه کارآمدتر و انعطافپذیرتر باشد.