2011-02-12 13 views
163

सी # में एक null-coalescing operator (?? के रूप में लिखा गया है) जो असाइनमेंट के दौरान आसान (संक्षिप्त) शून्य जांच के लिए अनुमति देता है:क्या सी # नल-कोलेसिंग ऑपरेटर का पाइथन बराबर है?

string s = null; 
var other = s ?? "some default value"; 

क्या कोई अजगर बराबर है?

मुझे पता है कि मैं कर सकता हूं:

s = None 
other = s if s else "some default value" 

लेकिन क्या एक छोटा रास्ता है (जहां मुझे s दोहराने की आवश्यकता नहीं है)?

+5

'??' ऑपरेटर को [पीईपी 505] (https://www.python.org/dev/peps/pep-0505/) के रूप में प्रस्तावित किया गया है। –

उत्तर

248
other = s or "some default value" 

ठीक है, यह स्पष्ट किया जाना चाहिए कि or ऑपरेटर कैसे काम करता है। यह एक बूलियन ऑपरेटर है, इसलिए यह एक बुलियन संदर्भ में काम करता है। यदि मूल्य बुलियन नहीं हैं, तो वे ऑपरेटर के प्रयोजनों के लिए बूलियन में परिवर्तित हो जाते हैं।

ध्यान दें कि or ऑपरेटर केवल True या False वापस नहीं लौटाता है। इसके बजाए, यह पहला ऑपरेंड लौटाता है यदि पहला ऑपरेंड सत्य का मूल्यांकन करता है, और यदि पहला ऑपरेंड झूठा मूल्यांकन करता है तो यह दूसरा ऑपरेंड देता है।

इस मामले में, अभिव्यक्ति x or yx देता है यदि यह True है या बूलियन में परिवर्तित होने पर सत्य का मूल्यांकन करता है। अन्यथा, यह y देता है। ज्यादातर मामलों के लिए, यह C♯ के अशक्त-कोलेसिंग ऑपरेटर की बहुत ही उद्देश्य के लिए काम करेंगे, लेकिन ध्यान रखें:

42 or "something" # returns 42 
0  or "something" # returns "something" 
None or "something" # returns "something" 
False or "something" # returns "something" 
"" or "something" # returns "something" 

आप का उपयोग करते हैं अपने चर s कुछ है कि या तो के लिए एक संदर्भ है धारण करने के लिए एक वर्ग या None का उदाहरण (जब तक आपकी कक्षा __nonzero__() और __len__() सदस्यों को परिभाषित नहीं करती है), यह समान अर्थशास्त्र का उपयोग नल-कोलेसिंग ऑपरेटर के रूप में करने के लिए सुरक्षित है।

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

कुछ भाषाओं में इस व्यवहार को Elvis operator के रूप में जाना जाता है।

+3

क्या यह वही काम करेगा? मेरा मतलब है, अगर यह वैध मान है तो यह टूट जाएगा लेकिन सच नहीं है? (मुझे पायथन नहीं पता है, इसलिए मुझे यकीन नहीं है कि 'सच्चाई' की अवधारणा लागू होती है।) – cHao

+6

संख्या 0, 'कोई नहीं', और खाली कंटेनर (स्ट्रिंग समेत) को झूठी माना जाता है, निरंतर ' FALSE'। बाकी सब कुछ सच माना जाता है। मैं कहूंगा कि यहां मुख्य खतरा यह होगा कि आपको एक वास्तविक लेकिन गैर-स्ट्रिंग मान मिलेगा, लेकिन यह कुछ कार्यक्रमों में कोई मुद्दा नहीं होगा। – kindall

+15

इस _other_ का उपयोग करने से डिफ़ॉल्ट मान प्राप्त होगा यदि एस कोई नहीं है ** या गलत **, जो कि वांछित नहीं हो सकता है। – pafcu

38

सख्ती से,

other = s if s is not None else "default value" 

अन्यथा एस = झूठी "डिफ़ॉल्ट मान" बन जाएगा, जो क्या इरादा था नहीं हो सकता।

def coalesce(*arg): 
    return reduce(lambda x, y: x if x is not None else y, arg) 

# Prints "banana" 
print coalesce(None, "banana", "phone", None) 

को कम() बेकार में सब कुछ खत्म पुनरावृति हो सकता है:

आप इस छोटे बनाना चाहते हैं, कोशिश

def notNone(s,d): 
    if s is None: 
     return d 
    else: 
     return s 

other = notNone(s, "default value") 
25

यहाँ एक समारोह है कि पहला तर्क है कि कोई भी नहीं है वापस आ जाएगी है तर्क तब भी है जब पहला तर्क कोई नहीं है, इसलिए आप इस संस्करण का भी उपयोग कर सकते हैं:

def coalesce(*arg): 
    for el in arg: 
    if el is not None: 
     return el 
    return None 
+14

'def coalesce (* arg): अगला लौटें ((अगर कोई नहीं है तो तर्क में एक के लिए) कोई नहीं) 'एक पंक्ति में आपके आखिरी उदाहरण जैसा ही है। – glglgl

+1

मुझे लगता है कि लोग सिंटैक्स इत्यादि के बारे में बताने के लिए चाहते हैं, लेकिन coalesce एक मनमाना तर्क सूची लेता है, तो यह वास्तव में शीर्ष जवाब होना चाहिए। –

+2

glglgl का सबसे अच्छा जवाब है। मैंने एक बड़े परीक्षण सरणी पर समय-समय पर उपयोग किया और कम कार्यान्वयन अस्वीकार्य रूप से धीमा है, बहु-पंक्ति/यदि संस्करण सबसे तेज़ है, और अगला कार्यान्वयन बहुत पीछे है। सादगी और एकता पर विचार करते समय अगला संस्करण सबसे अच्छा समग्र है। – clay

1

जोड़ने में की "या" व्यवहार के बारे में पीटर के जवाब देने के लिए ition: यह "तेज" यह

object = getCachedVersion() or getFromDB() 
+10

आप जिस शब्द को खोज रहे हैं वह "शॉर्ट सर्किट" है। – jpmc26

-3

दो कार्यों जैसी चीजों के लिए एक उपयोगी शॉर्टकट हो सकता है नीचे मैं हो पाया है है

>>> 1 or 5/0 
1 

इसलिए कभी-कभी कई परिवर्तनीय परीक्षण मामलों से निपटने के दौरान बहुत उपयोगी है।

def nz(value, none_value, strict=True): 
    ''' This function is named after an old VBA function. It returns a default 
     value if the passed in value is None. If strict is False it will 
     treat an empty string as None as well. 

     example: 
     x = None 
     nz(x,"hello") 
     --> "hello" 
     nz(x,"") 
     --> "" 
     y = "" 
     nz(y,"hello") 
     --> "" 
     nz(y,"hello", False) 
     --> "hello" ''' 

    if value is None and strict: 
     return_val = none_value 
    elif strict and value is not None: 
     return_val = value 
    elif not strict and not is_not_null(value): 
     return_val = none_value 
    else: 
     return_val = value 
    return return_val 

def is_not_null(value): 
    ''' test for None and empty string ''' 
    return value is not None and len(str(value)) > 0 
+1

इस तरह की चीजें थोड़ा अलग शब्दावली (जैसे "शून्य" और "एनजी" का पूरा समूह जोड़ती हैं, जिनमें से कोई भी पाइथन के संदर्भ में कुछ भी नहीं है), अन्य भाषाओं से आयात किया गया है, साथ ही वेरिएंट (सख्त या गैर-सख्त!) । यह केवल भ्रम जोड़ता है। स्पष्ट "कोई नहीं है" चेक वह है जो आपको उपयोग करना चाहिए। इसके अलावा आपको किसी भी शॉर्ट-कटिंग सेमेन्टिक्स का लाभ नहीं मिलता है जब आप फ़ंक्शन कॉल का उपयोग करते समय ऑपरेटर कर सकते हैं। – spookylukey

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