بیژن حجازی
بیژن حجازی
خواندن ۲ دقیقه·۳ سال پیش

Generators در پایتان

جنریتور ها (Generators) باعث افزایش چشمگیر در کارایی کدمون میشن.
جنریتور ها (Generators) باعث افزایش چشمگیر در کارایی کدمون میشن.

مقدمه

همون طوری که میدونی list ها مجموعه ای از مقادیر هستن که توی حافظه نگهداری میشن. حالا فرض کن به جای نگهداری مجموعه ای از مقادیر مشخص، فرمول درست کردن شون رو نگه داری کنیم و هر وقت که یکی شون رو لازم داشتیم محاسبه کنیم. این جاست که بحث Generator ها میاد وسط. بذار با مثال پیش بریم.

مثال مربعات

فرض کن میخایم list ای از اعداد رو به یک تابع بدیم و مربع شون رو بگیریم:

def squares(nums): results = [] for num in nums: results.append(num * num) return results

حاصل تابع بالا، جدا از این که هر لیستی با هر اندازه ای بهش بدیم، در هر صورت یک list خواهد بود که تک تک عناصرش عینا محاسبه میشه و در نهایت کل حاصل return میشه. حالا اگه بخایم همین تابع رو با فلسفه generator ها بزنیم:

def squares(nums): for num in nums: yield num * num

این جا دیگه نه return داریم و نه results بلکه هر دفعه باید از تابع next استفاده کنیم تا مقدار اون چرخه رو حساب کنیم. این طوری:

results = squares([1,2,3,4,5]) print(next(results)) # 1 print(next(results)) # 4 print(next(results)) # 5

تولید generator با comprehension

میشه بدون نیاز به تعریف یک function و به صورت مستقیم با استفاده از comprehension یک generator درست کرد. این طوری:

my_generator = (x*x for x in range(1,6)) print(next(my_generator)) # 1 print(next(my_generator)) # 4 print(next(my_generator)) # 9

در این حالت دیگه نیازی به تابع و کلیدواژه yield نیست.

نکات

برای تبدیل یک generator به یک لیست واقعی کافیه به تابع list بدیمش. مثل بقیه تبدیل ها!

real_list = list(my_generator)

اگر بیش از اندازه قابل تصور generator از تابع next استفاده کنیم حاصلی وجود نخواهد داشت که تابع next بخاد به ما برگردونه برای همین exception رخ میده. برای همین توصیه میشه از تابع next با احتیاط استفاده کنید یا این که توی بلوک try قرارش بدیم.

نتیجه گیری

تو پروژه های کوچیک اهمیت بین list واقعی و generator حس نمیشه ولی وقتی که حجم data مورد پردازش عظیم میشه (که تو دنیای واقعی اتفاقا این طوریه) تسلط به همین ویژگی های زبان پایتان هست که بین یک برنامه نویس Junior و Senior تفاوت ایجاد میکنه. خیلی وقت ها شنیدیم که میگن مثلا PHP در برابر Node اصلا سرعتی نداره. در یک دید کلی این درسته ولی یک برنامه نویس حرفه ای با تسلط به مباحثی مثل همین generator ها ممکنه کدی رو با PHP بنویسه که خیلی سریع باشه (generator ها مختص زبان پایتان نیستن). پس سعی کن که generator ها رو یاد بگیری.


برنامه نویسیپایتانپایتونتوسعه وبکدنویسی
سلام! نوشتن به منزله مطالعه «خود» هست. من بیشتر تو زمینه برنامه نویسی و روان شناسی مطلب میذارم. خوشحال میشم نظرات تون رو باهام در میون بذارین.
شاید از این پست‌ها خوشتان بیاید