2012-03-26 15 views
7

संभव डुप्लिकेट:
The Python yield keyword explainedअजगर 2.7 में उपज क्या करती है?

ठीक है, मैं शायद सवाल बुरी तरह phrased है, लेकिन इस स्थिति मैं है।

मैं जो मैं समझने की कोशिश कर रहा हूँ अजगर 2.7 में कोड की इस पंक्ति है:

yield (padding_zeros + number_string).encode("ascii") 

कोड की इस पंक्ति में, padding_zeros 'के परिवर्तनशील की एक श्रृंखला है 0 और number_string एक नंबर है एक स्ट्रिंग के रूप में जो 0 के बीच कोई संख्या हो सकती है, 10000 कहें।

मुझे पूरा भरोसा है कि .encode("ascii") केवल उपज के उत्पादन को एसीआई में परिवर्तित करता है।

मैं समुद्र में पूरी तरह से क्या हूं yield (padding_zeros + number_string) करता है।

मुझे पता है कि यह जनरेटर शुरू करता है लेकिन मैंने ऑनलाइन खोज करने और वाक्यविन्यास पर पढ़ने में काफी समय बिताया है, लेकिन मैं अभी भी काम नहीं कर सकता कि जेनरेटर वास्तव में करता है। यह मदद नहीं करता है कि यह मेरी पहली बार पाइथन को देख रहा है (मेरा अंतिम उद्देश्य इस कोड को सी # में परिवर्तित करना है)।

तो, मूल रूप से, कृपया कोई मुझे बता सकता है कि कोड की यह पंक्ति क्या करती है? क्या यह सिर्फ दो तारों को एक साथ जोड़ता है या क्या यह कुछ और जटिल करता है?

आगे संदर्भ के लिए, इस ब्लॉक कि कोड की है कि रेखा दिखाई देता है में:

for current_length in range(4, max_length + 1): 
    for i in range(0, pow(10, current_length)): 
     number_string = str(i) 
     padding_zeros = "0" * (current_length - len(number_string)) 
     yield (padding_zeros + number_string).encode("ascii") 

(max_length किया जा रहा है यह वास्तव में क्या लगता है - एक नंबर कुछ की अधिकतम लंबाई का संकेत)

किसी भी और सभी उत्तरों के लिए अग्रिम धन्यवाद (भले ही वे मुझे ऐसे फ्राइंग नोब न होने के बारे में बता रहे हों) :)

संपादित करें: उत्तर के लिए बहुत बहुत धन्यवाद - भले ही मैं केवल पी सबसे अच्छा जवाब के रूप में यह एक बहुत उपयोगी थे। और टिप्पणियों के लिए भी धन्यवाद - जैसा कि उनमें से कुछ ने इंगित किया है, What does the "yield" keyword do in Python? उपज, जेनरेटर और पुनरावृत्तियों के लिए एक बहुत अच्छी सामान्य मार्गदर्शिका है, भले ही मुझे इसे मेरी विशिष्ट स्थिति का उत्तर न मिले :)

+0

इस अजगर 2 या अजगर 3 है:

इस कोशिश? –

+0

हाय जॉर्ज, आपके प्रश्न का उत्तर यहां दिया गया है, मुझे लगता है: http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained – MattH

+0

यह उत्तर देखें: http://stackoverflow.com/questions/231767/द-पायथन-उपज-कीवर्ड-समझाया गया/231855 # 231855 –

उत्तर

6

ठीक है, आप जनरेटर के बारे में पता है, तो yield हिस्सा कोई स्पष्टीकरण की जरूरत है । ठीक।

तो वास्तव में वह पंक्ति क्या करती है? बहुत अधिक नहीं:

यह padding_zeros और number_string को संगत करता है और फिर परिणाम को ASCII में एन्कोड करता है। जो पाइथन 2.7 में एक नो-ऑप है क्योंकि स्ट्रिंग ASCII से शुरू होती है (इसमें केवल परिभाषा के अनुसार ASCII अंक होते हैं)।

पायथन 3 में, यह अलग होगा; यहां .encode() स्ट्रिंग को bytes ऑब्जेक्ट में परिवर्तित कर दिया होगा। लेकिन पायथन 2 में, यह कोई समझ नहीं आता है।

+0

धन्यवाद - यह हो सकता है कि यह कोड मूल रूप से पायथन 3 में लिखा गया था जो बताएगा कि यह पायथन 2 में कोई ऑप क्यों नहीं दिखाई देता है। हालांकि 100% निश्चित नहीं हो सकता है। आपके उत्तर के लिए धन्यवाद और इतनी अनजान होने के लिए खेद है। – GeorgePotter

1

इसमें मामला yield आलसी मूल्यांकन करने के लिए प्रयोग किया जाता है। अगले कोड बराबर हैं:

def f(...): 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      yield (padding_zeros + number_string).encode("ascii") 

result = list(f()) 

बनाम

def f(...): 
    result = list() 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      result.append((padding_zeros + number_string).encode("ascii")) 
    return result 

result = f() 

तुम बस आप कोड अनुवाद में एक दूसरे का अनुसरण करे।

+1

सिवाय इसके कि दूसरा संस्करण एक सूची देता है, जबकि जनरेटर प्रत्येक तत्व को एक-एक करके उत्पन्न करेगा। – Marcin

+0

बहुत बहुत धन्यवाद :) – GeorgePotter

+0

@ मार्सिन यकीन है। लेकिन मुझे नहीं लगता कि ओपी इसके बारे में परवाह करता है :) –

3

yield जनरेटर में वापसी की तरह है।

इस बिंदु पर कि yield निष्पादित किया गया है, जनरेटर फ़ंक्शन का निष्पादन बंद हो जाता है, और मान वापस आ जाता है।अंतर यह है कि जब जनरेटर को फिर से बुलाया जाता है, निष्पादन उपज कथन पर पुनरारंभ होता है, और तब तक जारी रहता है जब तक कि कोई अन्य उपज नहीं मारा जाता है, या एक (अनचाहे) अपवाद उठाया जाता है, या return हिट होता है। return या अपवाद जनरेटर को समाप्त कर देगा।

जनरेटर का बिंदु यह है कि कोई इसे x = next(generator) या x = generator.next() के रूप में आमंत्रित कर सकता है, और प्रत्येक बार जनरेटर के अंदर उपज से मूल्य प्राप्त होगा। जनरेटर भी पुनरावृत्त होते हैं, इसलिए उन्हें लूप के स्रोत के रूप में उपयोग किया जा सकता है: for x in generator: print x

सी # की तरह, . ऑपरेटर ऑपरेटर के बाईं ओर दिखाई देने वाली ऑब्जेक्ट पर दाईं ओर नामित विधि को आमंत्रित करता है। तदनुसार, (padding_zeros + number_string).encode("ascii")(padding_zeros + number_string) के परिणाम पर encode पर कॉल करता है।

encode के अर्थ के लिए, यहाँ देखें: http://docs.python.org/library/stdtypes.html#str.encode

भाषा संदर्भ के लिए (आप अजगर 2 का उपयोग कर रहे कल्पना करते हुए): http://docs.python.org/reference/index.html

+1

बहुत बहुत धन्यवाद :) – GeorgePotter

+0

@GorgePotter कोई समस्या नहीं है। एक उत्तर स्वीकार करने के लिए स्वतंत्र महसूस करें, और किसी अन्य को वोट दें जो आपको उपयोगी लगता है (एक बार जब आप मतदान करने में सक्षम होते हैं)। – Marcin

0

एक जनरेटर एक राज्यमाचिन है जो अजगर इंटरफ़ेस या पायथन में __iter__ लागू करता है। यह तब तक "उपज" के बाद इंतजार करेगा जब तक कि आप इसे अगले() पर कॉल न करें।

def my_gen(): 
    for current_length in range(4, max_length + 1): 
     for i in range(0, pow(10, current_length)): 
      number_string = str(i) 
      padding_zeros = "0" * (current_length - len(number_string)) 
      print "generate %s" % i 
      yield (padding_zeros + number_string).encode("ascii") 

for i in my_gen(): 
    print "iterate %s" % i 
+0

जनरेटर एक राज्यमाचिन -1 नहीं है: http://en.wikipedia.org/wiki/Finite-state_machine। इसके अतिरिक्त, प्राथमिक जनरेटर इंटरफ़ेस 'अगला' है। – Marcin

+0

मुझे लगता है कि यह है (एक बहुत ही सरल एक): अगले कॉल() के लिए प्रत्येक कॉल अपने राज्य को बदलता है, जो इसे आगे बढ़ने या रोकने के लिए अनुमति देता है। (मैंने दूसरे '__iter__' को 'अगली()' में संपादित किया) –

+0

यह राज्यमाचिन की परिभाषा नहीं है। – Marcin

संबंधित मुद्दे