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




operators ternary-operator conditional-operator python-2.5 (20)

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


Answers

مشغل ثلاثي في ​​لغات برمجة مختلفة

هنا أحاول فقط إظهار بعض الاختلاف الهام في ternary operator بين اثنين من لغات البرمجة.

مشغل Ternary في Javascript

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0

مشغل ثلاثي في ​​روبي

a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0

المشغل الثلاثي في ​​سكالا

val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0

مشغل ثلاثي في ​​برمجة R

a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0

المشغل الثلاثي في ​​بيثون

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0

الآن يمكنك رؤية جمال لغة python. قراءته للغاية وقابلة للصيانة.


انت تستطيع فعل ذالك :-

[condition] and [expression_1] or [expression_2] ;

مثال:-

print(number%2 and "odd" or "even")

هذا من شأنه أن يطبع "غريب" إذا كان الرقم فردي أو "حتى" إذا كان الرقم حتى.

النتيجة: - إذا كان الشرط صحيحًا ، فسيتم تنفيذ exp_1 وإلا فسيتم تنفيذ exp_2.

ملاحظة: - 0 ، بلا ، False ، emptylist ، يتم تقييم emptyString على أنه False. وأي بيانات غير 0 تقيم إلى True.

وإليك كيف يعمل:

إذا أصبح الشرط [condition] "True" ، فسيتم تقييم expression_1 ولكن لا expression_2. إذا كنا "و" شيئًا يحتوي على 0 (صفر) ، فستكون النتيجة دائمًا هي fasle. لذا في العبارة أدناه ،

0 and exp

لن يتم تقييم قيمة تعبير exp على الإطلاق لأن "و" مع 0 سيقيم دائماً إلى صفر ولا توجد حاجة لتقييم التعبير. هذه هي الطريقة التي يعمل بها المجمع ، بكل اللغات.

في

1 or exp

لن يتم تقييم exp التعبير على الإطلاق لأن "أو" مع 1 سيكون دائماً 1. لذا لن تهتم لتقييم التعبير التعبير لأن النتيجة ستكون 1 على أية حال. (طرق تحسين المترجم).

لكن في حالة

True and exp1 or exp2

لن يتم تقييم التعبير الثاني exp2 منذ True and exp1 قد يكون True عندما يكون exp1 غير صحيح.

بالمثل في

False and exp1 or exp2

لن يتم تقييم التعبير exp1 نظرًا لأن False معادل للكتابة 0 ويفعل "و" مع 0 سيكون 0 نفسه ولكن بعد exp1 لأنه "أو" يتم استخدامه ، فإنه سيتم تقييم التعبير exp2 بعد "أو".

ملاحظة: - يمكن استخدام هذا النوع من التفرعات باستخدام "أو" و "و" فقط عندما لا يكون في expression_1 قيمة Truth من False (أو 0 أو لا شيء أو emptylist [] أو emptystring ''.) حيث إذا أصبحت expression_1 خطأ ، سيتم تقييم expression_2 نظرًا لوجود "أو" بين exp_1 و exp_2.

في حال كنت لا تزال ترغب في جعلها تعمل في جميع الحالات بغض النظر عن قيم الحقيقة exp_1 و exp_2 ، فافعل ذلك: -

[condition] and ([expression_1] or 1) or [expression_2] ;


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

يسمح المشغل الشرطي الثلاثي ببساطة باختبار حالة في سطر واحد لتحل محل متعدد الأسطر في حالة جعل الكود مضغوطًا.

بناء الجملة :

[on_true] إذا كان [التعبير] آخر [on_false]

1- طريقة بسيطة لاستخدام المشغل الثلاثي:

# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min)  # Output: 10

2- الطريقة المباشرة لاستخدام tuples ، القاموس ، و lambda:

# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda  we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- يمكن كتابة المشغل الثلاثي على النحو التالي:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
        if a > b else "b is greater than a")

يمكن كتابة النهج أعلاه على النحو التالي:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
    if a > b:
        print("a is greater than b")
    else:
        print("b is greater than a")
else:
    print("Both a and b are equal") 
# Output: b is greater than a

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

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

، يصبح:

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

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


نعم ، تمت added في الإصدار 2.5.
الصيغة هي:

a if condition else b

يتم تقييم condition الأول ، ثم يتم إرجاع a أو b بناءً على قيمة condition Boolean
إذا تم تقييم condition إلى True يتم إرجاع ، يتم إرجاع 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 عادي بدلاً من شرطي.

ضع في اعتبارك أنه من المستغرب من قبل بعض Pythonistas لعدة أسباب:

  • يختلف ترتيب الحجج عن العديد من اللغات الأخرى (مثل C ، و Ruby ، ​​و Java ، إلخ) ، والتي قد تؤدي إلى أخطاء عندما يستخدمها أشخاص غير معتادون على سلوك Python "المفاجئ" (قد يقوموا بعكس الترتيب).
  • يجد البعض أنه "غير عملي" ، لأنه يتعارض مع التدفق الطبيعي للفكر (التفكير في الحالة أولاً ثم التأثيرات).
  • أسباب الأسلوب.

إذا كنت تواجه مشكلة في تذكر الطلب ، فتذكر أنه إذا قرأته بصوت عالٍ ، فإنك (تقريبًا) تقول ما تقصده. على سبيل المثال ، x = 4 if b > 8 else 9 تم قراءة x = 4 if b > 8 else 9 بصوت عالٍ حيث أن x will be 4 if b is greater than 8 otherwise 9 .

الوثائق الرسمية:


إذا تم تعريف متغير وتريد التحقق مما إذا كان له قيمة ، فيمكنك فقط a or b

def test(myvar=None):
    # shorter than: print myvar if myvar else "no Input"
    print myvar or "no Input"

test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)

سوف يخرج

no Input
no Input
no Input
hello
['Hello']
True

نعم فعلا:

لنفترض أنك تريد إعطاء متغير x بعض القيمة إذا كان بعض bool صحيحًا وبالمثل

X = 5 إذا كان هناك شيء آخر x = 10

X = [some value] if [if this true value first assessates] else [other value assessates]


نعم ، الثعبان لديه مشغل الثلاثي ، هنا هو بناء الجملة ومثالا رمز لإثبات نفسه :)

#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false


a= input("Enter the First Number ")
b= input("Enter the Second Number ")

print("A is Bigger") if a>b else print("B is Bigger")

للإصدارات السابقة لـ 2.5 ، هناك الحيلة:

[expression] and [on_true] or [on_false]

يمكن أن يعطي نتائج خاطئة عندما on_true لدى on_true قيمة منطقية زائفة. 1
على الرغم من أنها تتمتع بميزة تقييم التعابير من اليسار إلى اليمين ، وهو الأمر الأوضح في رأيي.

1. هل هناك ما يعادل C's "؟:" المشغل الثلاثي؟



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

(falseValue, trueValue)[test]

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

(falseValue, trueValue)[test == True]

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

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

من الوثائق :

تحمل التعبيرات الشرطية (التي يطلق عليها أحيانًا "المشغل الثلاثي") أدنى أولوية لجميع عمليات بايثون.

التعبير x if C else y أولاً بتقييم الحالة C ( وليس x )؛ إذا كان C صحيحًا ، يتم تقييم x ويتم إرجاع قيمته ؛ خلاف ذلك ، يتم تقييم y ويتم إرجاع قيمته.

انظر PEP 308 لمزيد من التفاصيل حول التعبيرات الشرطية.

جديد منذ الإصدار 2.5.


على الاطلاق ، وهو سهل الفهم بشكل لا يصدق.

general syntax : first_expression if bool_expression_is_true else second_expression

Example: x= 3 if 3 > 2 else 4 
# assigns 3 to x if the boolean expression evaluates to true or 4 if it is false

نعم فعلا.

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

@فوق:

لسوء الحظ، ال

(falseValue, trueValue)[test]

الحل ليس لديه سلوك الدائرة القصيرة. وبالتالي يتم تقييم falseValue و trueValue بغض النظر عن الشرط. يمكن أن يكون هذا دون المستوى الأمثل أو حتى عربات التي تجرها الدواب (أي أن كلا من trueValue و falseValue قد يكونان أساليب ولهما آثار جانبية).

حل واحد لهذا سيكون

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

(تأخر التنفيذ حتى يعرف الفائز ؛)) ، لكنه يقدم عدم تناسق بين الكائنات القابلة للاتصال وغير القابلة للاستدعاء. بالإضافة إلى ذلك ، فإنه لا يحل الحالة عند استخدام الخصائص.

وهكذا ، فإن القصة تذهب - الاختيار بين 3 حلول تم ذكرها هو المقايضة بين وجود ميزة الدارة القصيرة ، باستخدام على الأقل 2.5 python (IMHO ليست مشكلة بعد الآن) وعدم التعرض ل "trueValue-Evaluates-to-false" أخطاء.


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

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

بالنسبة إلى 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")

المصدر: ?:


Null combescing operator (؟؟)

تمت إضافة هذا المشغل في PHP 7.0 للحالة الشائعة التي تحتاج إلى استخدام مشغل الثلاثي بالتزامن مع isset() . تقوم بإرجاع المعامل الأول الخاص به إذا كان موجودًا وغير NULL . وإلا فإنها ترجع المعامل الثاني.

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>




python operators ternary-operator conditional-operator python-2.5