सवाल क्या पाइथन में एक टर्नरी सशर्त ऑपरेटर है?


यदि पाइथन में टर्नरी सशर्त ऑपरेटर नहीं है, तो क्या यह अन्य भाषा संरचनाओं का उपयोग करके अनुकरण करना संभव है?


4442


मूल


यद्यपि 2.5 से अधिक पुरानी पाइथन धीरे-धीरे इतिहास में बहती हैं, यहां पुरानी प्री-2.5 टर्नरी ऑपरेटर चाल की एक सूची है: "पायथन Idioms", पाठ 'सशर्त अभिव्यक्ति' के लिए खोज । विकिपीडिया भी काफी सहायक है Ж :-) - ジョージ
उपरोक्त टिप्पणी में संदर्भित पायथन 3.0 आधिकारिक दस्तावेज में, इसे "सशर्त_एक्सप्रेस" के रूप में जाना जाता है और यह बहुत ही स्पष्ट रूप से परिभाषित किया गया है। उस दस्तावेज़ में "टर्नरी" शब्द भी शामिल नहीं है, इसलिए आपको Google के माध्यम से इसे खोजने के लिए कठोर दबाव डाला जाएगा जबतक कि आपको पता न हो कि वास्तव में क्या देखना है। संस्करण 2 दस्तावेज कुछ और मददगार है और इसमें एक लिंक शामिल है "पीईपी 308", जिसमें इस प्रश्न से संबंधित कई दिलचस्प ऐतिहासिक संदर्भ शामिल हैं। - nobar
"टर्नरी" (तीन इनपुट होने) इस प्रवेग की एक परिणामी संपत्ति है, अवधारणा की परिभाषित संपत्ति नहीं। उदाहरण: एसक्यूएल है case [...] { when ... then ...} [ else ... ] end एक समान प्रभाव के लिए लेकिन सभी ternary पर नहीं। - user313114
आईएसओ / आईईसी 98 99 (सी प्रोग्रामिंग भाषा मानक) खंड 6.5.15 इसे "संदिग्ध ऑपरेटर" कहते हैं - user313114
विकिपीडिया इस लेख में पूरी तरह से शामिल है "?:"। - HelloGoodbye


जवाब:


हाँ यह था जोड़ा संस्करण 2.5 में।
वाक्यविन्यास है:

a if condition else b

प्रथम condition मूल्यांकन किया जाता है, फिर या तो a या b के आधार पर वापस आ गया है बूलियन का मूल्य condition
अगर condition का मूल्यांकन सच  a वापस आ गया है, अन्यथा b वापस आ गया है

उदाहरण के लिए:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

ध्यान दें कि सशर्त एक हैं अभिव्यक्ति, नहीं बयान। इसका मतलब है कि आप असाइनमेंट का उपयोग नहीं कर सकते हैं या pass या एक सशर्त में अन्य बयान:

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

ऐसे मामले में, आपको सामान्य का उपयोग करना होगा if एक सशर्त के बजाय बयान।


ध्यान रखें कि कई पायथनिस्टों द्वारा यह कई कारणों से फहराया गया है:

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

अगर आपको आदेश याद रखने में परेशानी हो रही है, तो याद रखें कि यदि आप इसे ज़ोर से पढ़ते हैं, तो आप (लगभग) कहते हैं कि आपका क्या मतलब है। उदाहरण के लिए, x = 4 if b > 8 else 9 के रूप में जोर से पढ़ा जाता है x will be 4 if b is greater than 8 otherwise 9

आधिकारिक दस्तावेज:


5299



ऑर्डर हालांकि कोडर के लिए अजीब लगता है f(x) = |x| = x if x > 0 else -x गणितज्ञों के लिए बहुत स्वाभाविक लगता है। आप इसे ज्यादातर मामलों में ए के रूप में भी समझ सकते हैं, सिवाय इसके कि सी को छोड़कर आपको बी करना चाहिए ... - yota
इसका उपयोग करते समय संचालन के आदेश से सावधान रहें। उदाहरण के लिए, रेखा z = 3 + x if x < y else y। अगर x=2 तथा y=1, आप उम्मीद कर सकते हैं कि 4 उत्पन्न करने के लिए, लेकिन यह वास्तव में 1 पैदा करेगा। z = 3 + (x if x > y else y) सही उपयोग है। - Kal Zekdor
मुद्दा यह था कि आप अतिरिक्त मूल्यांकन करना चाहते हैं बाद सशर्त मूल्यांकन किया जाता है, परिणाम के लिए मूल्य जोड़ने की तरह, आपको या तो दोनों तरफ अतिरिक्त अभिव्यक्ति जोड़ने की आवश्यकता होगी (z = 3 + x if x < y else 3 + y), या सशर्त समूह (z = 3 + (x if x < y else y) या z = (x if x < y else y) + 3) - Kal Zekdor
@Pred कोशिश करें print("OK" if status else "NOT OK") - BusyAnt
मुझे इस वाक्य रचनात्मक क्रम की अस्पष्ट विडंबना पसंद है जिसे @yota नामक किसी व्यक्ति द्वारा प्राकृतिक रूप में वर्णित किया जा रहा है। - nickf


आप एक टुपल में इंडेक्स कर सकते हैं:

(falseValue, trueValue)[test]

test वापस करने की जरूरत है सच या असत्य
हमेशा इसे लागू करने के लिए सुरक्षित हो सकता है:

(falseValue, trueValue)[test == True]

या आप अंतर्निर्मित का उपयोग कर सकते हैं bool() एक आश्वस्त करने के लिए बूलियन मूल्य:

(falseValue, trueValue)[bool(<expression>)]

594



ध्यान दें कि यह हमेशा सबकुछ का मूल्यांकन करता है, जबकि अगर / अन्य निर्माण केवल विजेता अभिव्यक्ति का मूल्यांकन करता है। - SilverbackNet
(lambda: print("a"), lambda: print("b"))[test==true]() - Dustin Getz
यह ध्यान दिया जाना चाहिए कि भीतर क्या है []एस एक मनमाना अभिव्यक्ति हो सकता है। इसके अलावा, सुरक्षा के लिए आप स्पष्ट रूप से लेखन के द्वारा सत्यता की जांच कर सकते हैं [bool(<expression>)]। bool() v2.2.1 के बाद समारोह चारों ओर रहा है। - martineau
यह कोड-गोल्फ के लिए बहुत अच्छा है, वास्तविक कोड के लिए इतना नहीं। यद्यपि मैं इसे इतना उपयोग कर चुका हूं कि मैं कभी-कभी दो स्ट्रिंग स्थिरांक के बीच चुनने जैसा कुछ स्पष्ट करते समय इसे एकता के लिए उपयोग करता हूं। - Claudiu
मैंने एक समान चाल की है - केवल एक या दो बार, लेकिन इसे किया - एक शब्दकोश में अनुक्रमणित करके True तथा False कुंजी के रूप में: {True:trueValue, False:falseValue}[test]  मुझे नहीं पता कि यह कम कुशल है, लेकिन यह कम से कम पूरे "सुरुचिपूर्ण" बनाम "बदसूरत" बहस से बचता है। कोई अस्पष्टता नहीं है कि आप एक int के बजाय एक बूलियन से निपट रहे हैं। - JDM


2.5 से पहले के संस्करणों के लिए, चाल है:

[expression] and [on_true] or [on_false]

यह गलत परिणाम दे सकता है जब on_true   एक झूठा बुलियन मूल्य है।1
यद्यपि इसका अधिकार बाईं ओर दिए गए अभिव्यक्तियों का मूल्यांकन करने का लाभ है, जो मेरी राय में स्पष्ट है।

1। क्या सी के "?:" टर्नरी ऑपरेटर के बराबर है?


246



इसका उपयोग (परीक्षण और [true_value] या [false_value]) [0] का उपयोग करना है, जो इस जाल से बचाता है। - ThomasH
टर्नरी ऑपरेटर आमतौर पर तेज़ी से निष्पादित करता है (कभी-कभी 10-25% तक)। - volcano
@ वोल्कोनो क्या आपके पास स्रोत है? - OrangeTux
@OrangeTux यहां डिस्सेबल कोड है। विधि थॉमसएच का उपयोग करने का सुझाव भी धीमा होगा। - mbomb007


expression1 अगर शर्त अन्य expression2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1

157



इस और शीर्ष उत्तर के बीच क्या अंतर है? - kennytm
यह टर्नरी ऑपरेटर के प्राथमिक उद्देश्य पर जोर देता है: मूल्य चयन। यह भी दिखाता है कि एक से अधिक टर्नरी को एक अभिव्यक्ति में एक साथ जोड़ा जा सकता है। - Roy Tinker
@ क्रैग, मैं सहमत हूं, लेकिन यह जानना भी सहायक होता है कि कोई ब्रांड्स नहीं होने पर क्या होगा। वास्तविक कोड में, मैं भी स्पष्ट माता-पिता को सम्मिलित करता हूं। - Jon Coombs
किसी भी तरह, मैं इसे शीर्ष उत्तर से बेहतर समझने में सक्षम हूं। - abhi divekar


से दस्तावेज़ीकरण:

सशर्त अभिव्यक्ति (कभी-कभी "टर्नरी ऑपरेटर" कहा जाता है) में सभी पायथन परिचालनों की सबसे कम प्राथमिकता होती है।

भाव x if C else y पहले स्थिति का मूल्यांकन करता है, सी (एक्स नहीं); अगर सी सच हैं, एक्स मूल्यांकन किया जाता है और इसका मूल्य वापस कर दिया जाता है; अन्यथा, y मूल्यांकन किया जाता है और इसका मूल्य वापस कर दिया जाता है।

देख पीईपी 308 सशर्त अभिव्यक्तियों के बारे में अधिक जानकारी के लिए।

संस्करण 2.5 के बाद से नया।


106





पायथन में एक सशर्त अभिव्यक्ति के लिए एक ऑपरेटर 2006 में जोड़ा गया था पायथन संवर्द्धन प्रस्ताव 308। इसका रूप आम से अलग है ?: ऑपरेटर और यह है:

<expression1> if <condition> else <expression2>

जो बराबर है:

if <condition>: <expression1> else: <expression2>

यहाँ एक उदाहरण है:

result = x if a > b else y

एक और वाक्यविन्यास जिसका उपयोग किया जा सकता है (2.5 से पहले संस्करणों के साथ संगत):

result = (lambda:y, lambda:x)[a > b]()

जहां ऑपरेंड हैं आलसी मूल्यांकन किया

एक और तरीका एक टुपल अनुक्रमणित करना है (जो अधिकांश अन्य भाषाओं के सशर्त ऑपरेटर के अनुरूप नहीं है):

result = (y, x)[a > b]

या स्पष्ट रूप से निर्मित शब्दकोश:

result = {True: x, False: y}[a > b]

एक और (कम विश्वसनीय), लेकिन उपयोग करने के लिए सरल तरीका है and तथा or ऑपरेटर:

result = (a > b) and x or y

हालांकि यह काम नहीं करेगा अगर x होने वाला False

एक संभावित कामकाज बनाना है x तथा y निम्न में सूचीबद्ध सूची या tuples:

result = ((a > b) and [x] or [y])[0]

या:

result = ((a > b) and (x,) or (y,))[0]

यदि आप शब्दकोशों के साथ काम कर रहे हैं, तो टर्नरी सशर्त उपयोग करने के बजाय, आप इसका लाभ उठा सकते हैं get(key, default), उदाहरण के लिए:

shell = os.environ.get('SHELL', "/bin/sh")

स्रोत: ?: विकिपीडिया में पायथन में


79





@up:

दुर्भाग्य से

(falseValue, trueValue)[test]

समाधान में शॉर्ट सर्किट व्यवहार नहीं है; इस प्रकार शर्त के बावजूद झूठी वैल्यू और सत्य वैल्यू का मूल्यांकन किया जाता है। यह सबोपेटिमल या यहां तक ​​कि छोटी गाड़ी भी हो सकती है (यानी दोनों सत्य वैल्यू और झूठी वैल्यू विधियां हो सकती हैं और साइड इफेक्ट्स हो सकती हैं)।

इसका एक समाधान होगा

(lambda: falseValue, lambda: trueValue)[test]()

(विजेता को ज्ञात होने तक निष्पादन में देरी हो जाती है;)), लेकिन यह कॉल करने योग्य और गैर-कॉल करने योग्य वस्तुओं के बीच असंगतता प्रस्तुत करता है। इसके अलावा, यह गुणों का उपयोग करते समय मामले को हल नहीं करता है।

और इसलिए कहानी जाती है - 3 उल्लिखित समाधानों के बीच चयन करना कम से कम पायथन 2.5 (आईएमएचओ अब कोई समस्या नहीं) का उपयोग करके शॉर्ट-सर्किट सुविधा रखने के बीच एक व्यापार-बंद है और "सत्यवैल-मूल्यांकन-से-झूठी" त्रुटियों।


72