जेनरेटर क्या है?
इटरेटर पायथन में एक महत्वपूर्ण भूमिका निभाते हैं। वे आपको एक ऐसा ऑब्जेक्ट बनाने की अनुमति देते हैं जिस पर पुनरावृति की जा सके। यह डेटा स्टोर करने का एक अच्छा तरीका है जिसे फॉर-इन लूप के माध्यम से एक्सेस किया जा सकता है।
इटरेटर के साथ परेशानी यह है कि इसे बनाने के लिए बहुत काम करना पड़ता है। वे उपयोगी हैं, लेकिन इन्हें काम करने के लिए आपको बहुत सारा कोड लिखना पड़ता है। जेनरेटर इस समस्या को हल करने में मदद करते हैं।
इस गाइड में, हम बात करेंगे कि पायथन जेनरेटर क्या हैं और आपको उनका उपयोग क्यों करना चाहिए। हम पायथन में एक जेनरेटर को भी लागू करेंगे ताकि आप समझ सकें कि वे कैसे काम करते हैं।
जेनरेटर क्या है?
एक जेनरेटर पायथन में इटरेटर बनाने का एक सरल तरीका है। यह एक फंक्शन है जो एक ऑब्जेक्ट लौटाता है जिस पर आप पुनरावृति कर सकते हैं।
जेनरेटर को अक्सर सिंटैक्टिक शुगर कहा जाता है। ऐसा इसलिए है क्योंकि वे आवश्यक रूप से पायथन में नई कार्यक्षमता नहीं जोड़ते। वे आपके कोड को अधिक कुशल बनाने में मदद करते हैं।
इटरेटर की तरह, आप केवल एक बार जेनरेटर पर पुनरावृति कर सकते हैं। ऐसा इसलिए है क्योंकि जेनरेटर ट्रैक रखते हैं कि उन पर कितनी बार पुनरावृति की गई है, और उन्हें रीसेट नहीं किया जा सकता।
आइए एक पायथन इटरेटर पर नज़र डालते हैं:
class Cookies:
def __init__(self, value):
self.value = value
def __iter__(self):
return self
def __next__(self):
return self.value
यह कोड Cookies नामक एक इटरेटर बनाता है। जब आप इस इटरेटर के माध्यम से डेटा पास करते हैं, तो इसे एक इटरेबल ऑब्जेक्ट में बदल दिया जाता है। इसका मतलब है कि आप फॉर-इन लूप का उपयोग करके डेटा के माध्यम से लूप कर सकते हैं। यदि आप इस कोड को देख रहे हैं और सोचते हैं कि यह वास्तव में लंबा है, तो ऐसा इसलिए है क्योंकि यह है।
जेनरेटर हमारे कोड को छोटा करने में मदद कर सकते हैं। आइए ऊपर दिए गए इटरेटर के लिए एक जेनरेटर लिखते हैं:
def cookies(value):
while True:
yield value
हमारे कोड का आकार काफी कम हो गया है। आइए चर्चा करते हैं कि यह कैसे काम करता है।
एक जेनरेटर एक फंक्शन है जिसमें रिटर्न स्टेटमेंट के बजाय yield कीवर्ड होता है। Yield स्टेटमेंट एक फंक्शन से एक मान लौटाते हैं।
एक yield स्टेटमेंट और एक रिटर्न स्टेटमेंट के बीच का अंतर यह है कि एक रिटर्न स्टेटमेंट एक फंक्शन को चलने से रोक देता है, जबकि एक yield स्टेटमेंट फंक्शन को रोक देता है और पुनरावृति जारी रखता है।
आइए हमारे सरल जेनरेटर फंक्शन पर पुनरावृति करने का प्रयास करते हैं:
for cookie in cookies("Raspberry"):
print(cookie)
हमारा कोड लौटाता है:
Raspberry Raspberry ...
यह कोड तब तक दोहराता रहता है जब तक हम अपना प्रोग्राम नहीं रोकते। ऐसा इसलिए है क्योंकि हमने एक while लूप का उपयोग किया है जो हमेशा के लिए चलता है। यह ज्यादातर मामलों में बहुत उपयोगी नहीं है। आइए एक जेनरेटर लिखते हैं जो तब रुकता है जब कोई क्रिया पूरी हो जाती है।
पायथन जेनरेटर कैसे लिखें
हमारे पास कुकीज़ की एक सूची है जिसे हम कंसोल पर प्रिंट करना चाहते हैं। यह सूची इस तरह दिखती है:
["Raspberry", "Choc-Chip", "Cinnamon", "Oat"]
इन्हें कंसोल पर प्रिंट करने के लिए, हम एक सरल जेनरेटर बना सकते हैं। एक नई पायथन फ़ाइल खोलें और निम्न कोड पेस्ट करें:
def print_cookies(cookies):
length = len(cookies)
for cookie in range(0, length):
yield cookies[cookie]
हमारा जेनरेटर हमारे द्वारा निर्दिष्ट सूची में प्रत्येक कुकी के माध्यम से जाता है और प्रत्येक कुकी को व्यक्तिगत रूप से लौटाता है। यह जेनरेटर अभी काम नहीं करता है। हमें इस पर पुनरावृति करने के लिए एक फॉर लूप का उपयोग करना होगा:
cookie_list = ["Raspberry", "Choc-Chip", "Cinnamon", "Oat"]
for c in print_cookies(cookie_list):
print(c)
हमने cookie_list नामक एक सरणी परिभाषित की है जो चार कुकीज़ की सूची स्टोर करती है। हमने फिर एक फॉर लूप सेट किया जो cookie_list में मानों के माध्यम से पुनरावृति करने के लिए हमारे जेनरेटर का उपयोग करता है।
हमारे फॉर लूप में प्रत्येक पुनरावृति के लिए, उत्पन्न ऑब्जेक्ट को कंसोल पर प्रिंट किया जाता है:
Raspberry Choc-Chip Cinnamon Oat
हमने कर दिखाया! यह जेनरेटर मान लौटाता है जब तक कि cookie_list वेरिएबल में प्रत्येक मान पर पुनरावृति नहीं की गई है।
जेनरेटर के उपयोग के मामलों की एक श्रृंखला है। मान लीजिए हमारे पास ऑर्डर की कीमतों की एक सूची है जिसे हम कुल करना चाहते हैं। हम निम्न कोड का उपयोग करके ऐसा कर सकते हैं:
def total_orders(orders):
length = len(orders)
total = 0
for o in range(0, length):
total += orders[o]
yield total
यह जेनरेटर एक सूची में सभी ऑर्डर्स के मूल्य का रनिंग टोटल रखेगा। प्रत्येक आइटम पर पुनरावृति के बाद, जेनरेटर ऑर्डर्स के वर्तमान कुल मूल्य को yield करेगा। आइए एक फॉर लूप लिखते हैं जो हमारे जेनरेटर का उपयोग करता है:
order_list = [2.30, 2.50, 1.95, 6.00, 7.50, 2.15]
for order in total_orders(order_list):
print(order)
हमारा कोड लौटाता है:
2.3 4.8 6.75 12.75 20.25 22.4
हमारे जेनरेटर ने order_list वेरिएबल में सभी ऑर्डर्स के संचयी मूल्य की गणना की है। सूची पर प्रत्येक पुनरावृति नया संचयी मूल्य लौटाती है।
जेनरेटर एक्सप्रेशन कैसे लिखें
जेनरेटर पहले से ही इटरेटर की तुलना में लिखने में आसान हैं। जेनरेटर एक्सप्रेशन की बदौलत साफ कोड लिखने की हमारी खोज यहीं नहीं रुकती।
जेनरेटर एक्सप्रेशन लिस्ट कॉम्प्रिहेंशन के समान हैं। जेनरेटर एक्सप्रेशन जेनरेटर की तरह एक समय में एक आइटम उत्पन्न करते हैं। यह लिस्ट कॉम्प्रिहेंशन से अलग है जो एक बार में पूरी सूची उत्पन्न करता है।
आइए हमारे कुकीज़ उदाहरण के लिए एक जेनरेटर लिखते हैं:
cookie_list = ["Raspberry", "Choc-Chip", "Cinnamon", "Oat"] cookie_generator = (cookie for cookie in cookie_list)
हमने cookie_list वेरिएबल में कुकीज़ की एक सूची परिभाषित की है। फिर हम एक जेनरेटर एक्सप्रेशन बनाते हैं। यह एक्सप्रेशन लिस्ट कॉम्प्रिहेंशन के लिए सिंटैक्स का उपयोग करता है लेकिन एक बड़ा अंतर: लिस्ट कॉम्प्रिहेंशन स्क्वायर ब्रैकेट्स के भीतर परिभाषित होते हैं, जबकि जेनरेटर राउंडेड ब्रैकेट्स के भीतर परिभाषित होते हैं।
आइए एक फॉर लूप बनाते हैं जो एक्सप्रेशन पर पुनरावृति करता है:
for cookie in cookie_generator:
print(cookie)
हमारा कोड लौटाता है:
Raspberry Choc-Chip Cinnamon Oat
इस जेनरेटर की प्रतिक्रिया हमारे पहले उदाहरण के समान ही है। हमारा सिंटैक्स काफी स्पष्ट है।
यह ध्यान रखना महत्वपूर्ण है कि जब आप एक जेनरेटर एक्सप्रेशन का उपयोग करके घोषित जेनरेटर पर पुनरावृति करते हैं, तो आप इसे फंक्शन के रूप में कॉल नहीं करते। हमारा cookie_generator जेनरेटर कोई इनपुट मान स्वीकार नहीं करता: इसमें पहले से ही वह कोड होता है जिसकी इसे cookie_list सूची पर पुनरावृति करने के लिए आवश्यकता होती है।
आपको जेनरेटर एक्सप्रेशन सिंटैक्स का उपयोग केवल तब करना चाहिए जब आपको एक ऐसा जेनरेटर लिखने की आवश्यकता हो जो एक सरल फंक्शन करता हो। मानों की सूची प्रिंट करना एक अच्छा उदाहरण है; सूची में मानों को एक विशिष्ट संख्या से गुणा करना एक और अच्छा उदाहरण है।
ऐसा इसलिए है क्योंकि जबकि जेनरेटर एक्सप्रेशन सिंटैक्स स्पष्ट है, यह मुख्य रूप से एक-लाइन एक्सप्रेशन के लिए डिज़ाइन किया गया है। यदि आपका जेनरेटर एक से अधिक लाइन कोड का उपयोग करेगा, तो इसे पहले इस लेख में चर्चा किए गए सिंटैक्स का उपयोग करके जेनरेटर फंक्शन के रूप में लिखें।
जेनरेटर का उपयोग क्यों किया जाता है?
जेनरेटर का उपयोग करने का प्राथमिक कारण यह है कि वे इटरेटर की तुलना में अधिक संक्षिप्त हैं।
जेनरेटर एक फंक्शन की तरह होते हैं और काम करने के लिए किसी __init__, __iter__, या __next__ स्टेटमेंट की आवश्यकता नहीं होती। यह एक इटरेटर के विपरीत है जिसे उन सभी तीन स्टेटमेंट्स की आवश्यकता होती है। इस व्यवहार का अर्थ है कि आप एक जेनरेटर को काफी कम कोड लाइनों में लागू कर सकते हैं जितना आप कर सकते थे यदि आप एक इटरेटर लिख रहे थे।
क्या अधिक है, जेनरेटर मेमोरी का उपयोग करने में कुशल हैं। जेनरेटर एक समय में केवल एक आइटम उत्पन्न करते हैं। वे परिणाम लौटाने से पहले मेमोरी में एक संपूर्ण अनुक्रम नहीं बनाते। यह जेनरेटर को बहुत व्यावहारिक बनाता है यदि आपको डेटा की एक बड़ी सूची पर पुनरावृति करने की आवश्यकता है।
यह काम करने का तरीका यह है कि इटरेटर एक आलसी मूल्यांकन विधि का उपयोग करते हैं। वे केवल एक इटरेबल ऑब्जेक्ट के अगले तत्व को उत्पन्न करते हैं जब उस आइटम का अनुरोध किया जाता है।
निष्कर्ष (और चुनौती)
जेनरेटर आपको अधिक पायथनिक इटरेटर बनाने की अनुमति देते हैं।
जेनरेटर __init__, __iter__, या __next__ स्टेटमेंट लिखे बिना इटरेटर प्रोटोकॉल का उपयोग करने वाले ऑब्जेक्ट्स को लिखना आसान बनाते हैं। जेनरेटर को फंक्शन के रूप में परिभाषित किया जाता है। वे मेन प्रोग्राम में मान वापस पास करने और अपने नियमित संचालन पर लौटने से पहले जेनरेटर को रोकने के लिए yield स्टेटमेंट का उपयोग करते हैं।
यदि आप एक चुनौती की तलाश में हैं, तो यहाँ कुछ विचार हैं:
- एक जेनरेटर लिखें जो एक स्ट्रिंग को उल्टा कर दे।
- एक जेनरेटर लिखें जो केवल उन मानों को लौटाता है जिनमें मानों की सूची से एक विशिष्ट शब्द होता है।
- एक जेनरेटर लिखें जो सूची में प्रत्येक संख्या को दो से गुणा करता है।
आगे पढ़ने के लिए, पायथन इटरेटर कैसे लिखें और उपयोग करें पर हमारे ट्यूटोरियल को देखें। अब आप पायथन में जेनरेटर के साथ एक विशेषज्ञ की तरह काम करना शुरू करने के लिए तैयार हैं!