2011-08-18 22 views
27

मैं जनरेटर का उपयोग कर रहा इस सरल उदाहरण की तरह खोजें सूचियों में प्रदर्शन करने के लिए:स्टॉपइटरेशन के बजाए कोई भी वापस करने के लिए पाइथन जनरेटर कैसे प्राप्त कर सकता हूं?

>>> a = [1,2,3,4] 
>>> (i for i, v in enumerate(a) if v == 4).next() 
3 

(बस उदाहरण थोड़ा फ्रेम करने के लिए, मैं ऊपर एक की तुलना में बहुत ज्यादा देर सूचियों का उपयोग कर रहा हूँ, और प्रविष्टियों एक हैं थोड़ा और अधिक जटिल int से। मैं इसे इस तरह से तो पूरे सूचियों अब हर बार मैं उन्हें खोज)

चल नहीं की जाएगी करना अगर मैं बजाय i == 666 है कि बदल जाएगा, यह एक StopIteration वापसी होगी क्योंकि यह कर सकते हैं ' में कोई भी 666 प्रविष्टि नहीं ढूंढें।

मैं इसे कैसे None बजाय वापसी कर सकते हैं? मैं इसे try ... except खंड में लपेट सकता हूं, लेकिन क्या ऐसा करने के लिए एक और अधिक पागल तरीका है?

+0

मैं पूछता हूँ तुम क्यों बातों के लिए खोज करने के लिए जनरेटर का उपयोग कर रहे कर सकते हैं? –

+0

यदि आप पहले से पारित कुछ की खोज करते हैं तो आप क्या होने की उम्मीद करते हैं? क्यों न केवल 'पायथनिक' तरीके का उपयोग करें जैसे 'अगर मैं इन: ...'? –

+0

@ मैनी डी, 'अगर मैं किसी में मदद नहीं करता हूं तो आप पाए गए आइटम की अनुक्रमणिका प्राप्त करना चाहते हैं। – senderle

उत्तर

70

आप अजगर उपयोग कर रहे हैं 2.6+ आप next में निर्मित समारोह, नहीं next विधि (जो 3.x में __next__ से बदला गया) का उपयोग करना चाहिए। next में निर्मित एक वैकल्पिक डिफ़ॉल्ट तर्क लेता है, तो इटरेटर समाप्त हो रहा है वापस जाने के लिए, बजाय StopIteration जुटाने की:

next((i for i, v in enumerate(a) if i == 666), None) 
+1

+1 अजगर में नए सामान यह पता लगाने की अगर और कुछ नहीं ..., इस यह करने के लिए सबसे अच्छा तरीका है। – senderle

+0

मुझे नहीं पता था कि अंतर्निहित फ़ंक्शन बदल गया था। यह सुनिश्चित करने के लिए यह एक बहुत आसान बनाता है – c00kiemonster

7

आप (कोई नहीं,) के साथ जनरेटर श्रृंखला कर सकते हैं:

from itertools import chain 
a = [1,2,3,4] 
print chain((i for i, v in enumerate(a) if v == 6), (None,)).next() 

लेकिन मुझे लगता है a.index (2) पूरी सूची है, जब 2 पाया जाता है, खोज समाप्त हो गया है पार नहीं होंगे। आप इस परीक्षण कर सकते हैं:

>>> timeit.timeit("a.index(0)", "a=range(10)") 
0.19335955439601094 
>>> timeit.timeit("a.index(99)", "a=range(100)") 
2.1938486138533335 
+1

के लिए धन्यवाद चेन चीज बहुत चालाक थी, उस बारे में नहीं सोचा था। हां 'इंडेक्स()' खराब नहीं है, लेकिन मेरे असली मामले में मैं वास्तव में इसका उपयोग नहीं कर सकता क्योंकि सूची प्रविष्टियां चर के बजाय ऑब्जेक्ट्स हैं। संपादित करें: मैं वस्तु ऑब्जेक्ट्स की तुलना में ऑब्जेक्ट विशेषताओं और अन्य मजेदार सामान की तुलना कर रहा हूं। – c00kiemonster

+1

यह कहने के लिए खेद है, लेकिन यह एक जटिल समाधान है। 'अगला' अंतर्निर्मित फ़ंक्शन पहले से ही इस कार्यक्षमता को एक साफ तरीके से प्रदान करता है। @ c00kiemonster, मुझे लगता है कि आपको [zeekay का जवाब] (http://stackoverflow.com/questions/7102050/how-can-i-get-a-python-generator-to-return-none-rather का उपयोग करना चाहिए (और स्वीकार करना चाहिए) -than-stopiteration/7102204 # 7102204)। – senderle

+0

कोई चिंता नहीं, अच्छा तरीका – c00kiemonster