2009-10-06 5 views
59

मेरे पास पाइथन में कुछ सूची समझ है जिसमें प्रत्येक पुनरावृत्ति अपवाद फेंक सकती है।पायथन में सूची समझ में अपवादों को कैसे संभाला जा सकता है?

उदाहरण के लिए, यदि मेरे पास है:

eggs = (1,3,0,3,2) 

[1/egg for egg in eggs] 

मैं 3 तत्व में एक ZeroDivisionError अपवाद मिल जाएगा।

मैं इस अपवाद को कैसे संभाल सकता हूं और सूची समझ का निष्पादन जारी रख सकता हूं?

एक ही रास्ता मैं के बारे में सोच सकते हैं एक सहायक समारोह का उपयोग करने के लिए है:

def spam(egg): 
    try: 
     return 1/egg 
    except ZeroDivisionError: 
     # handle division by zero error 
     # leave empty for now 
     pass 

लेकिन यह मेरे लिए थोड़ा बोझिल लग रहा है।

क्या Python में ऐसा करने का कोई बेहतर तरीका है?

नोट: यह एक सरल उदाहरण है कि मैं काल्पनिक (उपरोक्त, "उदाहरण के लिए" देखें) क्योंकि मेरी वास्तविक उदाहरण कुछ संदर्भ की आवश्यकता है। मुझे शून्य त्रुटियों से विभाजित करने से बचने में दिलचस्पी नहीं है, बल्कि सूची समझ में अपवादों को संभालने में दिलचस्पी नहीं है।

+2

अपवादों को संभालने के लिए एक अभिव्यक्ति जोड़ने के लिए एक [पीईपी 463] (https://www.python.org/dev/peps/pep-0463/) है। आपके उदाहरण में यह '[1/अंडे ज़ीरोडिविजन एरर को छोड़कर होगा: अंडा के लिए कोई नहीं (1,3,0,3,2)] '। लेकिन यह अभी भी ड्राफ्ट मोड में है। मेरी आंत महसूस यह है कि यह स्वीकार नहीं किया जा रहा है। इम्हो एक्सप्रेशन बहुत गन्दा हो सकता है (कई अपवादों की जांच कर रहा है, जिसमें अधिक जटिल संयोजन (एकाधिक लॉजिकल ऑपरेटर, जटिल समझ, आदि) – cfi

+1

ध्यान दें कि इस * विशिष्ट * उदाहरण के लिए, आप 'np में उपयुक्त सेटिंग्स के साथ एक numpy 'ndarray' का उपयोग कर सकते हैं। seterr'। इसका परिणाम '1/0 = nan' होगा। लेकिन मुझे एहसास है कि यह अन्य स्थितियों को सामान्यीकृत नहीं करता है जहां यह आवश्यकता उत्पन्न होती है। – gerrit

उत्तर

55

कोई फैसला करने के लिए है पाइथन में अंतर्निहित अभिव्यक्ति जो आपको अपवादों के मामले में अपवाद को अनदेखा कर देती है (या वैकल्पिक मान & सी वापस लौटाती है), इसलिए, एक सूची समझ में अपवादों को संभालने के लिए, शब्दशः बोलना असंभव है, क्योंकि एक सूची समझ एक अभिव्यक्ति है अभिव्यक्ति, और कुछ नहीं (यानी, संख्या कथन, और केवल कथन अपवादों को पकड़/अनदेखा/संभाल सकते हैं)।

फ़ंक्शन कॉल अभिव्यक्तियां हैं, और फ़ंक्शन निकायों में आपके द्वारा दिए गए सभी कथन शामिल हो सकते हैं, इसलिए एक कार्य में अपवाद-प्रवण उप-अभिव्यक्ति के मूल्यांकन को दर्शाते हुए, जैसा कि आपने देखा है, एक व्यवहार्य कार्यवाही है (अन्य, जब व्यवहार्य हो, वे मानों पर जांच कर सकते हैं जो अपवादों को उकसा सकते हैं, साथ ही अन्य उत्तरों में भी सुझाव दिया जा सकता है)।

प्रश्न की सही प्रतिक्रिया "सूची समझ में अपवादों को कैसे संभालना है" सभी इस सत्य का हिस्सा व्यक्त कर रहे हैं: 1) सचमुच, यानी समझदारी से स्वयं समझ में, आप नहीं कर सकते; 2) व्यावहारिक रूप से, आप किसी फ़ंक्शन में नौकरी का प्रतिनिधि देते हैं या जब यह संभव हो तो त्रुटि प्रवण मूल्यों की जांच करें। आपका दोहराया दावा है कि यह कोई जवाब नहीं है, इस प्रकार निराधार है।

+6

मैं देखता हूं। तो एक पूरा जवाब यह होगा कि मुझे या तो चाहिए: 1. फ़ंक्शन का उपयोग करें 2. सूची समझ का उपयोग न करें 3. इसे संभालने के बजाय अपवाद को रोकने का प्रयास करें। –

+8

मुझे "सूची समझ में अपवादों को कैसे संभालना है" के उत्तर के हिस्से के रूप में "सूची समझों का उपयोग नहीं करना" नहीं है, लेकिन मुझे लगता है कि आप इसे "एलएक्सएक्सिक इन_ एलसी" के संभावित परिणाम के रूप में देख सकते हैं, यह संभव नहीं है अपवादों को संभालने के लिए ", जो वास्तव में शाब्दिक उत्तर का पहला हिस्सा है। –

+0

क्या आप जनरेटर अभिव्यक्ति या जनरेटर समझ में कोई त्रुटि प्राप्त कर सकते हैं? – Steve

18

आप

[1/egg for egg in eggs if egg != 0] 

इस का उपयोग बस तत्वों को शून्य हैं छोड़ देगा कर सकते हैं।

+10

यह सूची समझ में अपवादों को संभालने के तरीके के उत्तर का जवाब नहीं देता है। –

+4

umm, हाँ, यह करता है। यह अपवादों को संभालने की आवश्यकता को रोकता है। हाँ, यह हर समय सही समाधान नहीं है, लेकिन यह एक आम बात है। – Peter

+1

मैं समझता हूं। मैं टिप्पणी वापस लेता हूं (हालांकि मैं इसे हटा नहीं पाऊंगा चूंकि उस छोटी 'चर्चा' उत्तर पर सुधार करती है) –

8

कोई बेहतर तरीका नहीं है। मामलों का एक बहुत में आप परिहार उपयोग कर सकते हैं पीटर की तरह करता है

आपका दूसरा विकल्प comprehensions

eggs = (1,3,0,3,2) 

result=[] 
for egg in eggs: 
    try: 
     result.append(egg/0) 
    except ZeroDivisionError: 
     # handle division by zero error 
     # leave empty for now 
     pass 

का उपयोग नहीं करने के लिए आप अप करने के लिए है कि क्या है कि और अधिक बोझिल है या नहीं

+0

मैं यहां समझ का उपयोग कैसे करूं? –

+0

@ नाथन: आप नहीं करेंगे। gnibbler कहते हैं: * कोई बेहतर तरीका नहीं है * – SilentGhost

+0

क्षमा करें ... मैंने अपने जवाब में 'नहीं' को याद किया :-) –

58

मुझे पता है इस सवाल का काफी पुराना है, लेकिन आप यह भी आसान बात इस तरह का बनाने के लिए एक सामान्य समारोह बना सकते हैं:

def catch(func, handle=lambda e : e, *args, **kwargs): 
    try: 
     return func(*args, **kwargs) 
    except Exception as e: 
     return handle(e) 

फिर, अपनी समझ में:

eggs = (1,3,0,3,2) 
[catch(lambda : 1/egg) for egg in eggs] 
[1, 0, ('integer division or modulo by zero'), 0, 0] 

आप कर सकते हैं निश्चित रूप से डिफ़ॉल्ट हैंडल फ़ंक्शन जो कुछ भी आप चाहते हैं (कहें कि आप डिफ़ॉल्ट रूप से 'कोई नहीं' वापस लौटना चाहते हैं)।

आशा है कि इससे आपको इस प्रश्न के भविष्य में या भविष्य में दर्शकों की मदद मिलेगी!

नोट: पायथन 3 में, मैं केवल 'हैंडल' तर्क कीवर्ड बनाउंगा, और इसे तर्क सूची के अंत में रखूंगा। यह वास्तव में तर्कों को पार कर जाएगा और इस तरह के अधिक प्राकृतिक पकड़ के माध्यम से।

+1

चरम रूप से उपयोगी, धन्यवाद। जबकि मैं सैद्धांतिक टिप्पणियों से सहमत हूं, यह एक समस्या को हल करने के लिए एक व्यावहारिक दृष्टिकोण दिखाता है जो मैंने बार-बार किया है। – Paul

+1

ग्रीट उत्तर। एक मॉड जो मैं सुझाव दूंगा वह भी 'Args' और' kwargs' को संभालने के माध्यम से गुजर रहा है। इस तरह आप एक हार्डकोडेड '0' के बजाय 'अंडा' कह सकते हैं, या एक अपवाद के रूप में आप कर सकते हैं। –

+1

आप अपवाद प्रकार को वैकल्पिक तर्क के रूप में भी अपनाना चाहते हैं (अपवाद प्रकारों को पैरामीटरेट किया जा सकता है?), ताकि सभी अपवादों को अनदेखा करने के बजाय अप्रत्याशित अपवादों को ऊपर फेंक दिया जा सके। – 00prometheus

1

मुझे लगता है कि एक सहायक कार्य, जैसा कि प्रारंभिक प्रश्न और ब्रायन हेड भी पूछता है, अच्छा है और बोझिल नहीं है। जादू कोड की एक पंक्ति जो सभी काम करता है, हमेशा संभव नहीं है, इसलिए यदि कोई for लूप से बचना चाहता है तो एक सहायक कार्य एक आदर्श समाधान है। हालांकि मैं इसे इस एक के लिए संशोधित करेगा:

# A modified version of the helper function by the Question starter 
def spam(egg): 
    try: 
     return 1/egg, None 
    except ZeroDivisionError as err: 
     # handle division by zero error   
     return None, err 

उत्पादन इस [(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)] हो जाएगा। इस जवाब के साथ आप किसी भी तरह से जारी रखने के लिए पूर्ण नियंत्रण में हैं।

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