2009-11-26 12 views
5

पर मूल्यांकन करता है मेरे पास कुछ चर हैं और मैं सत्य का मूल्यांकन करने वाले पहले व्यक्ति को चुनना चाहता हूं, या फिर डिफ़ॉल्ट मान वापस कर सकता हूं।सही चर का चयन करने के लिए पाइथोनिक तरीका जो सही

उदाहरण के लिए मैं a, b, और c है। मेरे मौजूदा कोड:

result = a if a else (b if b else (c if c else default)) 

एक और दृष्टिकोण मैं विचार कर रहा था:

result = ([v for v in (a, b, c) if v] + [default])[0] 

लेकिन वे दोनों गंदा लग रहा है, तो वहाँ एक और अधिक pythonic तरीका है?

+0

मुझे "पायथनिक" के बारे में पता नहीं है लेकिन मुझे पहले पसंद है। अच्छा और lispy और पढ़ने के लिए आसान :) – mtvee

+6

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

+3

ध्यान दें कि पायथन में आप चर परिभाषित नहीं करते हैं, आप ऑब्जेक्ट्स पर नाम बांधते हैं। –

उत्तर

20

क्या आपका मतलब bool(value)==True के लिए पहला मान लौटा रहा था? तो फिर तुम सिर्फ इस तथ्य पर भरोसा कर सकते कि boolean operators return last evaluated argument: एक चर नहीं "परिभाषित" है

result = a or b or c or default 
+1

एनबी (ओपी में) खाली स्ट्रिंग ('" "') में झूठा है बूलियन मान ('बूल (" ") == झूठा'); इसे ध्यान में रखें यदि आप इसे अपने कार्यक्रम में "झूठा" नहीं मानते हैं। '()' (खाली टुपल), '{}' (खाली dict), '[]' (खाली सूची) और शून्य (किसी भी संख्यात्मक प्रकार में) पर लागू होता है। – tzot

17

हैं, तो आप इसके नाम का उपयोग नहीं कर सकते हैं। तो 'ए' के ​​किसी भी संदर्भ में नेमरर अपवाद उठाता है।

दूसरी ओर, यदि आप की तरह कुछ है:

a = None 
b = None 
c = 3 

आप

default = 1 
r = a or b or c or default 
# r value is 3 
+0

क्या दो विकल्प में से कोई भी पूछताछ प्रस्तुत नहीं करेगा जैसा कि नामकर्ता एक ही नाम ErrorException में चलाया गया है? – donut

+1

यह सही है। आप इसे कुछ निर्दिष्ट करने से पहले एक चर नहीं पढ़ सकते हैं। –

1

अगर यह हर मामले में काम करता है पता नहीं है क्या कर सकते हैं, लेकिन यह इस मामले के लिए काम करता है।

a = False 
b = "b" 
c = False 
default = "default" 
print a or b or c or default # b 
1

इस बारे में कैसे?

a=None 
b=None 
c=None 
val= reduce(lambda x,y:x or y,(a,b,c,"default")) 
print val 

ऊपर प्रिंट "default"। यदि किसी भी इनपुट को परिभाषित किया गया है, तो val में पहले परिभाषित इनपुट होगा।

5

इतने लंबे समय के default का मूल्यांकन करता है के रूप में सही पर: आप अन्य उत्तर देने के लिए (कुछ इस तरह विपरीत कर सकता है

result = next((x for x in (a, b, c, d , e, default) if x)) 
+4

यदि आपने 'अगली' का उपयोग करने का निर्णय लिया है, तो आप इसके 'डिफ़ॉल्ट' तर्क का उपयोग भी कर सकते हैं – abyx

2

यह एक समाधान है जहाँ आप नहीं परिभाषित करने के लिए है है 'लापता' बजाय समारोह स्ट्रिंग की एक सूची दे वैरिएबल संदर्भ: या तो None या False) होने के रूप में मान:

b = 6 
c = 8 

def first_defined(items): 
    for x in items: 
     try: 
      return globals()[x] 
      break 
     except KeyError: 
      continue 

print first_defined(["a", "b", "c"]) 

आदेश NameErrors से बचने के लिए जब ए, बी या सी से परिभाषित नहीं है (आप गैर-मौजूदा संदर्भ पास नहीं कर सकते हैं)। यदि आप 'ग्लोबल्स()' स्कोप के बाहर चर का उपयोग कर रहे हैं, तो आप Getattr को इसके डिफ़ॉल्ट तर्क के साथ उपयोग कर सकते हैं।

-

तो एक, बी और सी परिभाषित कर रहे हैं, मैं कुछ इस तरह के लिए जाना चाहते हैं (तथ्य यह है कि एक खाली स्ट्रिंग, कोई नहीं है या गलत एक बूलियन False का मूल्यांकन पर विचार):

a = None 
b = 6 
c = 8 

def firstitem(items): 
    for x in items: 
     if x: 
      return x 
      break 
     else: 
      continue 

print firstitem([a, b, c]) 
+1

आपको वापसी के बाद 'ब्रेक' करने की आवश्यकता नहीं है: आप पहले से ही लूप से बाहर हैं। आपको लूप के अंत में 'else: जारी रखने' की भी आवश्यकता नहीं है: यही वही होगा। –

1

यदि defined से आपका मतलब ever assigned any value whatsoever to in any scope accessible from here है, तो एक "अपरिभाषित" चर का उपयोग करने का प्रयास करने से नामइरर अपवाद (या उसके कुछ सबक्लास को बढ़ाया जाएगा, लेकिन नेमरर को पकड़ने से सबक्लास भी मिल जाएगा)।तो, प्रदर्शन करने के लिए सबसे आसान तरीका है, सचमुच, बिल्कुल अजीब कार्य आप के बारे में पूछते हैं, है:

for varname in ('a', 'b', 'c'): 
    try: return eval(varname) 
    except NameError: pass 
return default 

किसी भी कथित समाधान की कमी एक कोशिश/छोड़कर "परिभाषित" के लिए उपरोक्त अर्थ के तहत काम नहीं करेगा। विशिष्ट क्षेत्रों की खोज के आधार पर दृष्टिकोण या तो अन्य क्षेत्रों को याद करेंगे, या eval आपके लिए ऐसा करने के लिए स्कोप-ऑर्डरिंग तर्क को दोहराने की कोशिश करके काफी जटिल हो जाएंगे।

यदि "परिभाषित" द्वारा आप वास्तव में "एक मान निर्दिष्ट करते हैं जो सत्य (जो झूठ के विपरीत) का मूल्यांकन करता है, यानी, सभी मूल्य वास्तव में परिभाषित (लेकिन गलत हो सकता है, और आप पहले चाहते हैं इसके बजाय सही मूल्य), तो पहले से प्रस्तावित a or b or c or default सबसे आसान दृष्टिकोण बन जाता है। लेकिन यह एक पूरी तरह से अलग है (और यहां तक ​​कि वीरडर!) शब्द "परिभाषित" शब्द के लिए है! -)

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