मुख्य सामग्री पर जाएं
मॉड्यूल 6 · पाठ 3 का 4पाठ्यक्रम में 23/36~10 min
मॉड्यूल पाठ (3/4)

जेनरेटर अभिव्यक्ति

एक जनरेटर अभिव्यक्ति एक सूची समझ की तरह है, लेकिन साथ में वर्गाकार कोष्ठकों के स्थान पर कोष्ठक। अंतर नाटकीय है: यह मेमोरी में कोई सूची नहीं बनाता है, यह ऑन-डिमांड तत्व तैयार करता है, एक समय में एक.

Python
gen = (n * n for n in range(1_000_000))
# istantaneo, memoria costante: nessun calcolo ancora fatto

list_comp = [n * n for n in range(1_000_000)]
# alloca 1M di int in memoria

आलस्य (आलसी मूल्यांकन)

जनरेटर तब तक कुछ नहीं करता जब तक कोई अगला मान न मांगे:

Python
gen = (n * n for n in range(5))
next(gen)    # 0    (calcolato adesso)
next(gen)    # 1
next(gen)    # 4
# ... e così via, fino a StopIteration

यह समाप्त हो जाता है: सभी तत्वों का उपभोग करने के बाद, यह हमेशा के लिए खाली हो जाता है। इसका पुन: उपयोग करने के लिए, आपको इसे पुनः बनाना होगा।

इसका उपयोग कब करना है

जब आप परिणामों को किसी फ़ंक्शन पर पास करते हैं जो उन्हें क्रम में उपभोग करता है:

Python
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costante

sum, any, all, max, min, "".join(...) सभी जनरेटर स्वीकार करते हैं। यदि बाहरी फ़ंक्शन को केवल कॉल कोष्ठक की आवश्यकता है, तो आप ऐसा कर सकते हैं जनरेटर का अपना छोड़ दें:

Python
sum((n * n for n in range(10)))    # OK
sum(n * n for n in range(10))      # IDENTICO, più leggibile

any और all: शॉर्ट-सर्किट

any(...) और all(...) उत्तर मिलते ही दोहराना बंद कर देते हैं। जनरेटर के साथ, निम्नलिखित तत्वों की गणना भी नहीं की जाती है।

Python
nums = [1, 2, 3, 4, 5]
any(n > 3 for n in nums)    # True (si ferma a 4)
all(n > 0 for n in nums)    # True
all(n > 2 for n in nums)    # False (si ferma a 1)

पैटर्न: आलसी पाइपलाइन

Python
righe = (linea.strip() for linea in testo.splitlines())
non_vuote = (r for r in righe if r)
prime_dieci = []
for r in non_vuote:
    prime_dieci.append(r)
    if len(prime_dieci) == 10:
        break

विशाल इनपुट पर भी कोई मध्यवर्ती सूची नहीं।

योग, कोई भी, सभी के साथ जनरेटर का उपभोग करना

जेनरेटर एक्सप्रेशन उन फ़ंक्शंस पर सीधे जाने के लिए एकदम सही हैं जो पुनरावर्तनीय चीज़ों का उपभोग करते हैं, जैसे sum(), any(), या all()। इस मामले में, आप जनरेटर अभिव्यक्ति के बाहरी कोष्ठक को केवल यह लिखकर छोड़ सकते हैं:

Python
squares_sum = sum(x**2 for x in range(10))

यह आपके कोड को साफ़ और अत्यधिक मेमोरी-कुशल रखता है।

इसे अजमाएं

व्यायाम#python.m6.l3.e1
प्रयास: 0लोड हो रहा है...

योग() के अंदर जनरेटर अभिव्यक्ति का उपयोग करके 1 से 100 (समावेशी) तक की संख्याओं के वर्गों के योग की गणना करें। इसे `टोट` को सौंपें। 'टोट' का मूल्यांकन करें.

संपादक लोड हो रहा है...
संकेत दिखाएँ

रेंज(1,101) में 100 शामिल है।

3 प्रयासों के बाद समाधान उपलब्ध है

व्यायाम की समीक्षा करें

व्यायाम#python.m6.l3.e2
प्रयास: 0लोड हो रहा है...

दिए गए `words = ['ciao', 'mondo', 'PYTHON', 'java']`, यह जांचने के लिए जनरेटर एक्सप्रेशन के साथ Any() का उपयोग करें कि क्या कम से कम एक शब्द अपरकेस (.isupper()) है। परिणाम को `has_uppercase` पर निर्दिष्ट करें। `has_uppercase` का मूल्यांकन करें।

संपादक लोड हो रहा है...
संकेत दिखाएँ

कोई(p.isupper() शब्दों में p के लिए)

3 प्रयासों के बाद समाधान उपलब्ध है

अतिरिक्त चुनौती

व्यायाम#python.m6.l3.e3
प्रयास: 0लोड हो रहा है...

Use a generator expression passed directly to the `sum()` function to calculate the sum of the squares of all integers from 1 to 100 inclusive. Store the result in `total_sum` and evaluate it.

संपादक लोड हो रहा है...
संकेत दिखाएँ

श्रेणी(1,101) में x के लिए total_sum = sum(x**2) लिखें। दोहरे कोष्ठकों की आवश्यकता नहीं है.

3 प्रयासों के बाद समाधान उपलब्ध है