पाठ 37 / 49

जेनरेटर और yield

बहुत कम memory में विशाल sequences process करने के लिए yield और generator expressions से values lazily बनाएँ।

एक जेनरेटर फ़ंक्शन

yield किसी फ़ंक्शन को रोकता है और मान वापस देता है; अगली कॉल पर फ़ंक्शन वहीं से फिर शुरू होता है — पूरी लिस्ट मेमोरी में बनाने की ज़रूरत नहीं।

def count_up_to(n):
    i = 1
    while i <= n:
        yield i
        i += 1

for num in count_up_to(5):
    print(num)          # 1 2 3 4 5, one at a time

जेनरेटर एक्सप्रेशन

जेनरेटर एक्सप्रेशन [] की जगह () वाला list comprehension जैसा दिखता है, और यह भी मान आलसी तरीके से बनाता है।

squares = (n * n for n in range(1_000_000))  # nothing computed yet
print(next(squares))   # 0
print(next(squares))   # 1
print(sum(n * n for n in range(10)))   # 285

त्वरित जाँच: विशाल अनुक्रम के लिए list की बजाय generator क्यों बेहतर है?

  • यह हर स्थिति में तेज़ चलता है
  • यह अपने-आप आइटम क्रमबद्ध करता है
  • यह सभी को मेमोरी में रखने के बजाय आइटम आलसी तरीके से बनाता है
  • यह हमेशा ज्यादा memory उपयोग करता है
Answer

यह सभी को मेमोरी में रखने के बजाय आइटम आलसी तरीके से बनाता है — जेनरेटर माँग पर एक-एक मान बनाता है, इसलिए विशाल या अनंत अनुक्रम को मेमोरी में फ़िट होने की ज़रूरत नहीं।