क्या रूबी में पायथन का "या बराबर" कार्य है?


83

यदि नहीं, तो ऐसा करने का सबसे अच्छा तरीका क्या है?

अभी मैं (एक django परियोजना के लिए) कर रहा हूँ:

if not 'thing_for_purpose' in request.session:
    request.session['thing_for_purpose'] = 5

लेकिन यह बहुत अजीब है। रूबी में यह होगा:

request.session['thing_for_purpose'] ||= 5

जो बहुत अच्छा है।


23
ध्यान दें कि कोड के ये दो बिट्स वास्तव में बहुत भिन्न हैं: पायथन संस्करण इसे 5 पर सेट करता है यदि यह बिल्कुल भी तानाशाह में नहीं है, जहां रूबी संस्करण इसे 5 पर सेट करता है यदि यह किसी भी गलत मान पर सेट है।
ग्लेन मेनार्ड

2
@Genn, बहुत अलग नहीं है , लेकिन काफी अलग है। चूंकि एक अनधिकृत हैश मूल्य रिटर्न nil(बूलियन संदर्भ में गलत) इस मुहावरे का उपयोग अक्सर उस प्रयोजन के लिए किया जाता है जिसका उपयोग शॉन ने किया है। मुहावरे केवल तभी काम करते हैं, यदि निश्चित रूप से, nilऔर falseहैश में वैध मूल्य नहीं हैं (जो कि बहुत बार सच है, इसलिए मुहावरा ठीक है)
घोड़े का शरीर

8
@banister: मुझे नहीं पता कि कोई "बहुत" और "काफी" के बीच की रेखा कहाँ खींच सकता है, लेकिन यह मुद्दा समान कथन नहीं है, और अंतर को समझना महत्वपूर्ण है। (झूठी बहुत बार एक हैश में एक वैध मूल्य होता है, जो आपको तब काटेगा जब आप एक बूलियन फ़ील्ड के लिए डिफ़ॉल्ट को सही पर सेट करना चाहते हैं; यह रूबी के मुहावरे का एक महत्वपूर्ण कमी है।)
ग्लेन मेनार्ड

हाँ, पायथन उदाहरण परिभाषित-या के समान अधिक है , जैसे //=कि आप पर्ल में पाते हैं । मुझे लगता है कि ||=पर्ल से भी उत्पत्ति होती है।
draegtun

आह अच्छे अंक, सभी। मैंने इस अंतर पर ध्यान नहीं दिया था।
सीन डब्ल्यू।

जवाबों:


188

स्वीकार किए गए उत्तर dicts के लिए अच्छा है, लेकिन शीर्षक रूबी के || = ऑपरेटर के बराबर सामान्य है। कुछ करने का एक आम तरीका || = Python में है

x = x or new_value

36
इस उत्तर की संभावना है कि Google खोज से यहां आने वाले लोग क्या खोज रहे हैं।
gradi3nt

यह वास्तव में सबसे अच्छा जवाब है।
AdamC

6
ध्यान दें कि रूबी के विपरीत, यह कोड केवल तभी काम करेगा जब xपहले परिभाषित किया गया हो (उदाहरण के लिए Noneएक वर्ग आरंभीकरण विधि में सेट )।
oli

3
यह सच है, यह बिल्कुल रूबी की तरह व्यवहार नहीं करता है = || एक और बात देखने के लिए एक्स की 'सच्चाई' है। यदि x == 0 पायथन में, तो आपको new_value मिल जाएगा क्योंकि 0 को झूठा माना जाता है, लेकिन रूबी में आपको 0.
यूसुफ शेडी

1
क्या यह उतना ही कुशल है = || = = एक असाइनमेंट तब तक नहीं करता है जब तक कि यह अशक्त न हो, लेकिन यह हमेशा एक असाइनमेंट करता है। क्या अजगर संकलक चतुर है जितना मुझे लगता है कि यह है?
jsarma

17

dictहै setdefault()

तो अगर request.sessionएक dict:

request.session.setdefault('thing_for_purpose', 5)

अस्पष्ट समान लेकिन किसी भी तरह से रूबी के समतुल्य नहीं = = ||
AdamC

1
यह महत्वपूर्ण है कि डिफ़ॉल्ट अभिव्यक्ति का मूल्यांकन किया जाता है भले ही कुंजी पहले से सेट हो। मूल प्रश्न को डिफ़ॉल्ट मान का मूल्यांकन किए बिना, या कुंजी को एक से अधिक बार, या दोनों तक पहुंचने के बिना हल करने का कोई तरीका नहीं है।
slinkp

13

सटीक उत्तर: नहीं। पायथन में एक भी अंतर्निहित ऑपरेटर नहीं है opजो अनुवाद कर सकता x = x or yहै x op y

लेकिन, यह लगभग करता है। बिटवाइज़ या-बराबर ऑपरेटर ( |=) ऊपर वर्णित कार्य करेगा, अगर दोनों ऑपरेंड को गुहा के साथ बूलियन के रूप में माना जा रहा है। (क्या चेतावनी है? उत्तर पाठ्यक्रम से नीचे है।)

सबसे पहले, कार्यक्षमता का मूल प्रदर्शन:

x = True
x    
Out[141]: True

x |= True
x    
Out[142]: True

x |= False
x    
Out[143]: True

x &= False
x    
Out[144]: False

x &= True
x    
Out[145]: False

x |= False
x    
Out[146]: False

x |= True
x   
Out[147]: True

कारण यह है कि अजगर को कड़ाई से टाइप नहीं किया जाता है, और इस प्रकार भले ही मूल्यों को एक अभिव्यक्ति के रूप में बूलियन के रूप में माना जा रहा हो, अगर वे एक बिटवाइज ऑपरेटर को दिए गए शॉर्ट-सर्कुलेट नहीं होंगे। उदाहरण के लिए, मान लें कि हमारे पास एक बूलियन फ़ंक्शन था जो एक सूची को साफ करता है और Trueयदि तत्व हटाए गए थे तो रिटर्न देता है:

def  my_clear_list(lst):
    if not lst:
        return False
    else:
        del lst[:]
        return True

अब हम छोटे परिचालित व्यवहार को इस प्रकार देख सकते हैं:

x = True
lst = [1, 2, 3]
x = x or my_clear_list(lst)
print(x, lst)

Output: True [1, 2, 3]

हालांकि, orबिटवाइज़ या ( |) में स्विच करने से शॉर्ट-सर्किट को हटा दिया जाता है, इसलिए फ़ंक्शन my_clear_listनिष्पादित होता है।

x = True
lst = [1, 2, 3]
x = x | my_clear_list(lst)
print(x, lst)

Output: True []

ऊपर, x = x | my_clear_list(lst)के बराबर है x |= my_clear_list(lst)


10

यदि आप इसे मिडलवेयर या किसी चीज़ में कर रहे हैं, तो डिफ़ॉल्ट सेट करना समझ में आता है, लेकिन यदि आपको किसी अनुरोध के संदर्भ में डिफ़ॉल्ट मान चाहिए:

request.session.get('thing_for_purpose', 5) # gets a default

बोनस: यहाँ कैसे ||=पायथन में वास्तव में एक करने के लिए है।

def test_function(self, d=None):
    'a simple test function'
    d = d or {}

    # ... do things with d and return ...

1

सामान्य तौर पर, आप उपयोग कर सकते हैं dict[key] = dict.get(key, 0) + val

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.