[Python] هل لدى بايثون مشغل شرطي ثلاثي؟


Answers

يمكنك الفهرسة في tuple:

(falseValue, trueValue)[test]

يحتاج test إلى إرجاع True أو False .
قد يكون أكثر أمانًا دائمًا تنفيذه على أنه:

(falseValue, trueValue)[test == True]

أو يمكنك استخدام bool() المضمن لضمان قيمة Boolean :

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

إذا لم يكن لبيثون مشغل شرطي ثلاثي ، فهل من الممكن محاكاة واحدة باستخدام تركيبات لغة أخرى؟




نعم فعلا.

>>> b = (True if 5 > 4 else False)
>>> print b
True



هل لدى بايثون مشغل شرطي ثلاثي؟

نعم فعلا. من ملف القواعد :

test: or_test ['if' or_test 'else' test] | lambdef

جزء الاهتمام هو:

or_test ['if' or_test 'else' test]

لذلك ، تكون العملية الشرطية الثلاثية هي الشكل:

expression1 if expression2 else expression3

سيتم تقييم expression3 بشكل تكاسل (أي ، يتم تقييمه فقط إذا كان expression2 غير صحيح في سياق منطقي). وبسبب التعريف العودي ، يمكنك تسلسلها إلى أجل غير مسمى (رغم أنها قد تعتبر أسلوبًا سيئًا).

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

ملاحظة حول الاستخدام:

لاحظ أن كل ذلك يجب أن يتبع مع أي else . قد يجد الأشخاص الذين يتعلمون قائمة الفهم وتعبيرات المولد ذلك درسًا صعبًا للتعلم - لن يعمل ما يلي ، حيث تتوقع بايثون تعبيرًا ثالثًا عن آخر:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

الأمر الذي يرفع SyntaxError: invalid syntax . إذاً ، ما سبق هو إما جزء غير مكتمل من المنطق (ربما كان المستخدم يتوقع وجود أمر ما في الحالة الخاطئة) أو ما قد يكون المقصود هو استخدام التعبير 2 كفلتر - يلاحظ أن ما يلي هو بايثون قانوني:

[expression1 for element in iterable if expression2]

expression2 يعمل كمرشح للفهم القائمة ، وليس المشغل الشرطي الثلاثي.

صيغة بديلة لحالة أكثر ضيقة:

قد تجد أنه مؤلم بعض الشيء لكتابة ما يلي:

expression1 if expression1 else expression2

يجب أن يتم تقييم expression1 مرتين مع الاستخدام أعلاه. يمكن أن تحد من تكرار إذا كان مجرد متغير محلي. ومع ذلك ، فإن مصطلح Pythonic المشترك والأداء لهذا الاستخدام هو استخدام or سلوك الاختصار:

expression1 or expression2

وهو ما يعادل في علم الدلالة. لاحظ أن بعض أدلة الأنماط قد تحد من هذا الاستخدام على أساس الوضوح - فهي تحزم الكثير من المعنى في تركيب قليل جدًا.




قد تجد في كثير من الأحيان

cond and on_true or on_false

ولكن هذا يؤدي إلى مشكلة عند on_true == 0

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

حيث تتوقع من المشغل الثلاثي العادي هذه النتيجة

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1



أكثر من مجرد إجابة (لا داعي لتكرار ما هو واضح لوقت المليون) ، لكني أستخدمه أحيانًا كاختصار في هذه الشبكات:

if conditionX:
    print('yes')
else:
    print('nah')

، يصبح:

print('yes') if conditionX else print('nah')

بعض (العديد من :) قد يتغذى عليه على أنه unpythonic (حتى ، ruby-ish :) ، لكنني شخصياً أجده أكثر طبيعية - أي كيف يمكنك التعبير عنه بشكل طبيعي ، بالإضافة إلى جاذبية أكثر بصرية في كتل كبيرة من الكود.




هناك خيار ثلاثي كما هو مذكور في إجابات أخرى ، ولكن يمكنك أيضًا محاكاة ذلك باستخدام "أو" إذا كنت تتحقق من قيمة منطقية أو بلا:

>>> a = False
>>> b = 5
>>> a or b
5

>>> a = None
>>> a or b
5



In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1



بالنسبة إلى Python 2.5 والإصدارات الأحدث ، هناك بنية محددة:

[on_true] if [cond] else [on_false]

في Pythons الأقدم ، لا يتم تشغيل مشغل ثلاثي ولكن يمكن محاكاته.

cond and on_true or on_false

على الرغم من ذلك ، توجد مشكلة محتملة ، والتي إذا قيّمت cond إلى True و يقيّم on_true إلى False ثم يتم إرجاع on_true بدلاً من on_true . إذا كنت تريد هذا السلوك فإن الطريقة جيدة ، وإلا استخدم هذا:

{True: on_true, False: on_false}[cond is True] # is True, not == True

والتي يمكن تغليفها بواسطة:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

واستخدمت بهذه الطريقة:

q(cond, on_true, on_false)

وهو متوافق مع جميع إصدارات بايثون.




تمت إضافة عامل للتعبير الشرطي في Python عام 2006 كجزء من اقتراح تحسين Python 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")

المصدر: ?:




expression1 إذا كان الشرط else expression2

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