2009-03-02 19 views
7

में मैं अन्य के लिए उपयोग कर रहा हूं मैं पाइथन के for...else syntax का एक बड़ा प्रशंसक हूं - यह आश्चर्यजनक है कि यह कितनी बार लागू होता है, और यह कोड को सरल कैसे प्रभावी ढंग से कर सकता है।पाइथन जेनरेटर

हालांकि, मैं एक जनरेटर में इसका इस्तेमाल करने के लिए एक अच्छा तरीका खोज निकाला नहीं गया है उदाहरण के लिए,:

def iterate(i): 
    for value in i: 
     yield value 
    else: 
     print 'i is empty' 

उपरोक्त उदाहरण में, मैं print बयान को केवल तभी i क्रियान्वित किया जा करना चाहते हैं खाली है। हालांकि, else केवल break और return का सम्मान करता है, i की लंबाई के बावजूद इसे हमेशा निष्पादित किया जाता है।

यदि इस तरह से for...else का उपयोग करना असंभव है, तो इसका सबसे अच्छा तरीका क्या है ताकि print कथन केवल तब तक निष्पादित किया जा सके जब कुछ भी नहीं मिलता है?

उत्तर

11

आप एक जनरेटर है, जो एक StopIteration अपवाद फेंक चाहिए की परिभाषा को तोड़ने रहे हैं जब यात्रा पूरा हो गया है

तो (जो स्वत: एक जनरेटर समारोह में एक वापसी कथन द्वारा नियंत्रित किया जाता):

def iterate(i): 
    for value in i: 
     yield value 
    return 

बेस्ट बुला कोड एक खाली इटरेटर के मामले को संभालने के जाने के लिए:

count = 0 
for value in iterate(range([])): 
    print value 
    count += 1 
else: 
    if count == 0: 
     print "list was empty" 

ऊपर करने का एक क्लीनर तरीका हो सकता है, लेकिन यह चाहिए ठीक काम करें, और नीचे किसी भी तरह की 'एक सूची जैसे इटेटरेटर का इलाज' में शामिल नहीं होता है।

+3

वापसी जनरेटर के अंत में निहित है। इसे शामिल करने की कोई ज़रूरत नहीं है। – recursive

+0

मैं सोच रहा था, लेकिन मैंने सोचा कि मैं इसे यहां स्पष्ट कर दूंगा। – Triptych

+2

+1: "प्रिंट मैं खाली हूं" किसी और की समस्या है, जेनरेटर नहीं। –

-2

यदि सरल है तो और क्या?

def iterate(i): 
    if len(i) == 0: print 'i is empty' 
    else: 
     for value in i: 
      yield value 
+0

तर्क है कि मेरे पास परिभाषित लेन नहीं हो सकता है, इसलिए यह समस्याग्रस्त है। – Kiv

+0

रिकर्सिव के उत्तर के रूप में वही समस्या, कम या ज्यादा। – Triptych

5

ऐसा करने के कुछ तरीके हैं। तुम हमेशा इस्तेमाल कर सकते हैं Iterator सीधे:

def iterate(i): 
    try: 
     i_iter = iter(i) 
     next = i_iter.next() 
    except StopIteration: 
     print 'i is empty' 
     return 

    while True: 
     yield next 
     next = i_iter.next() 

लेकिन अगर आप क्या तर्क i से उम्मीद के बारे में अधिक पता है, तुम अधिक संक्षिप्त हो सकता है:

def iterate(i): 
    if i: # or if len(i) == 0 
     for next in i: 
      yield next 
    else: 
     print 'i is empty' 
     raise StopIteration() 
0

यदि यह असंभव है इसके लिए उपयोग करें ... इस तरह से, इसके लिए सबसे अच्छा तरीका क्या है ताकि प्रिंट स्टेटमेंट केवल तभी निष्पादित किया जा सके जब कुछ भी नहीं मिलता है?

अधिकतम मैं के बारे में सोच सकते हैं:

 

>>> empty = True 
>>> for i in [1,2]: 
...  empty = False 
... if empty: 
...  print 'empty' 
... 
>>> 
>>> 
>>> empty = True 
>>> for i in []: 
...  empty = False 
... if empty: 
... print 'empty' 
... 
empty 
>>> 
 
3

पहले कुछ उत्तर संक्षेप में, यह इस तरह से हल किया जा सकता है:

def iterate(i): 
    empty = True 
    for value in i: 
     yield value 
     empty = False 

    if empty: 
     print "empty" 

तो वहाँ वास्तव में कोई "बाकी है "खंड शामिल है।

3

जैसा कि आप ध्यान देते हैं, for..else केवल break का पता लगाता है। इसलिए यह केवल तभी लागू होता है जब आप कुछ ढूंढते हैं और फिर रोकें।

यह आपके उद्देश्य पर लागू नहीं है क्योंकि यह जनरेटर है, लेकिन क्योंकि आप को रोक दिए बिना सभी तत्वों को संसाधित करना चाहते हैं (क्योंकि आप उन्हें सब कुछ देना चाहते हैं, लेकिन यह बात नहीं है)।

तो जनरेटर या नहीं, आपको वास्तव में बोर के समाधान में बुलियन की आवश्यकता है।

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