मेरे पास कई पायथन जनरेटर हैं, जिन्हें मैं एक नए जनरेटर में जोड़ना चाहता हूं। मैं yield
कथन के समूह का उपयोग करके हाथ से लिखित जनरेटर द्वारा आसानी से ऐसा कर सकता हूं।itertools या हाथ से लिखित जनरेटर - क्या बेहतर है?
दूसरी तरफ, itertools
मॉड्यूल इस तरह की चीजों के लिए बनाया गया है और मेरे लिए ऐसा लगता है कि जनरेटर बनाने के लिए पाइथोनिक तरीका मुझे itertools
मॉड्यूल के विभिन्न पुनरावृत्तियों को एक साथ प्लग करना है।
हालांकि, समस्या में हाथ में, यह जल्द ही काफी जटिल हो जाता है (जेनरेटर को एक तरह का राज्य बनाए रखने की आवश्यकता होती है --- उदाहरण के लिए कि पहले या बाद के आइटम संसाधित किए जा रहे हैं ---, i-th आउटपुट आगे i-th इनपुट आइटम्स की स्थितियों पर निर्भर करता है और विभिन्न इनपुट सूचियों को जेनरेटेड सूची में शामिल होने से पहले अलग-अलग संसाधित किया जाना चाहिए।
मानक समस्याकर्ताओं की संरचना के रूप में जो मेरी समस्या का समाधान करेगी --- देय स्रोत कोड लिखने की एक-आयामी प्रकृति के लिए --- लगभग समझ में नहीं आता है, मुझे आश्चर्य है कि मानक itertools
जेनरेटर बनाम हाथ से लिखित जेनरेटर फ़ंक्शंस (मूल और अधिक उन्नत मामलों में) का उपयोग करने के कोई फायदे हैं। असल में, मुझे लगता है कि 90% मामलों में, एच और लिखित संस्करणों को पढ़ने के लिए बहुत आसान है --- संभवतः चेनिंग इटरेटर्स की कार्यात्मक शैली की तुलना में उनकी अधिक अनिवार्य शैली के कारण। a
और b
एक ही लंबाई (इनपुट डेटा) के दो iterables हो:
संपादित
आदेश मेरी समस्या को वर्णन करने में, यहाँ एक (खिलौना) उदाहरण है। a
के आइटम पूर्णांक से युक्त हैं, b
के आइटम खुद को पुनरावृत्त कर रहे हैं, जिनके व्यक्तिगत आइटम तार हैं।
from itertools import *
def generator2(a, b):
return (z for i, s, c in izip(a, b, count())
for y in (("First line" if c == 0 else "Some later line",),
("The parameter vanishes.",) if i == 0
else ("The parameter is:", i),
("The strings are:",),
islice((x for t in s for x in (',', t)), 1, None))
for z in y)
:
from itertools import *
def generator(a, b):
first = True
for i, s in izip(a, b):
if first:
yield "First line"
first = False
else:
yield "Some later line"
if i == 0:
yield "The parameter vanishes."
else:
yield "The parameter is:"
yield i
yield "The strings are:"
comma = False
for t in s:
if comma:
yield ','
else:
comma = True
yield t
अगर मैं जनरेटर भाव और itertools
मॉड्यूल का उपयोग कर कार्यात्मक शैली में एक ही कार्यक्रम लिख, मैं की तरह कुछ के साथ अंत: उत्पादन निम्नलिखित जनरेटर फ़ंक्शन के परिणाम के अनुरूप होना चाहिए
उदाहरण
>>> a = (1, 0, 2), ("ab", "cd", "ef")
>>> print([x for x in generator(a, b)])
['First line', 'The parameter is:', 1, 'The strings are:', 'a', ',', 'b', 'Some later line', 'The parameter vanishes.', 'The strings are:', 'c', ',', 'd', 'Some later line', 'The parameter is:', 2, 'The strings are:', 'e', ',', 'f']
>>> print([x for x in generator2(a, b)])
['First line', 'The parameter is:', 1, 'The strings are:', 'a', ',', 'b', 'Some later line', 'The parameter vanishes.', 'The strings are:', 'c', ',', 'd', 'Some later line', 'The parameter is:', 2, 'The strings are:', 'e', ',', 'f']
यह poss है मेरे पहले समाधान की तुलना में अधिक सुरुचिपूर्ण लेकिन यह एक बार-लिखने-समझने-बाद-समझने वाले कोड के टुकड़े जैसा दिखता है। मैं सोच रहा हूं कि मेरे जेनरेटर लिखने के इस तरीके के पास पर्याप्त फायदे हैं जो किसी को ऐसा करना चाहिए।
पीएस: मुझे लगता है कि कार्यात्मक समाधान के साथ मेरी समस्या का हिस्सा यह है कि पाइथन में कीवर्ड की मात्रा को कम करने के लिए, "के लिए", "if" और "else" जैसे कुछ कीवर्ड अभिव्यक्तियों में उपयोग के लिए पुनर्नवीनीकरण किए गए हैं ताकि अभिव्यक्ति में उनकी नियुक्ति का उपयोग किया जा सके (जेनरेटर अभिव्यक्ति z for x in a for y in x for z in y
में क्रमशः क्लासिक for
लूप: for x in a: for y in x: for z in y: yield z
में ऑर्डर करने से कम प्राकृतिक, कम से कम मेरे लिए दिखता है)।
पुनश्च: मैं सिर्फ बाहर पाया है मैं जनरेटर समारोह से चिपक है। यह एक काम कर सकता है, मैं जनरेटर अभिव्यक्तियों के साथ नहीं कर सकता, अर्थात् अपवादों को पकड़ना। – Marc