سؤال

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

هل كانت مفيدة؟

المحلول

نعم لقد كان هذا وأضاف في الإصدار 2.5. بناء جملة التعبير هو:

a if condition else b

أولا condition يتم تقييمها، ثم بالضبط واحد من أي a أو b يتم تقييمها وعادتها بناء على منطقية قيمة ال condition. وبعد إذا condition يقيم إلى True, ، ومن بعد a يتم تقييم وعاد ولكن b يتم تجاهلها، أو متى b يتم تقييم وعاد ولكن a يتم تجاهلها.

هذا يسمح بالدائرة القصيرة لأنه عندما condition صحيح فقط a يتم تقييمها و b لا يتم تقييمها على الإطلاق، ولكن عندما condition هو خطأ فقط b يتم تقييمها و a لا يتم تقييمها على الإطلاق.

علي سبيل المثال:

>>> '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

ومع ذلك، يمكنك استخدام التعبيرات الشرطية لتعيين متغير مثل ذلك:

x = a if True else b

فكر في التعبير المشروط على أنه التبديل بين قيمتين. من المفيد للغاية عندما تكون في موقف "قيمة واحدة أو"، ولكن لا يفعل الكثير آخر.

إذا كنت بحاجة إلى استخدام البيانات، فعليك استخدام عادي if بيان بدلا من مشروط التعبير.


ضع في اعتبارك أنه عبوس بعض البيرثونستاس لعدة أسباب:

  • أمر الحجج يختلف عن تلك الكلاسيكية condition ? a : b مشغل Ternary من العديد من اللغات الأخرى (مثل C، C ++، GO، PERL، RUBY، Java، JavaScript، إلخ)، والتي قد تؤدي إلى الأخطاء عندما يكون الأشخاص غير المألوفين مع سلوك Python "المفاجئ" استخدامه (قد يعكس ترتيب الوسيطة ).
  • يجد البعض أنه "غير عملي"، لأنه يتعارض مع التدفق الطبيعي للفكر (التفكير في الحالة أولا ثم الآثار).
  • أسباب أسلوبية. (على الرغم من أن "المضمنة if' يمكن ان يكون حقا مفيد، وجعل النصي الخاص بك موجزة، فإنه حقا يعقد رمزك)

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

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

نصائح أخرى

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

(falseValue, trueValue)[test]

test يحتاج إلى العودة صحيح أو خطأ شنيع.
قد يكون أكثر أمانا لتنفيذها دائما على النحو التالي:

(falseValue, trueValue)[test == True]

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

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

للإصدارات قبل 2.5، هناك خدعة:

[expression] and [on_true] or [on_false]

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

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

u003Cexpression 1> إذا u003Ccondition> آخر u003Cexpression 2>

a = 1
b = 2

1 if a > b else -1 
# Output is -1

1 if a > b else -1 if a < b else 0
# Output is -1

من وثائق:

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

التعبير x if C else y أولا تقييم الحالة، جيم (ليس X.) إذا جيم صحيح، عاشر يتم تقييمه ويتم إرجاع قيمته؛ غير ذلك، Y. يتم تقييمه ويتم إرجاع قيمته.

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

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

تمت إضافة مشغل للتعبير الشرطي في بيثون في عام 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]()

حيث المعاملات تم تقييمه بتكاسل.

هناك طريقة أخرى من خلال فهرسة Tuple (والتي لا تتفق مع المشغل الشرطي لمعظم اللغات الأخرى):

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")

مصدر: ؟: في بيثون في ويكيبيديا

لسوء الحظ، ال

(falseValue, trueValue)[test]

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

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

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

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

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

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

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

المشغل الثلاثي في ​​جافا سكريبت

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 2.5 و Newer هناك بناء جملة محدد:

[on_true] if [cond] else [on_false]

في Pythons الأقدم، لم يتم تنفيذ مشغل Ternary ولكن من الممكن محاكاة ذلك.

cond and on_true or on_false

رغم ذلك، هناك مشكلة محتملة، إذا cond يقيم إلى True و on_true يقيم إلى False ومن بعد on_false يتم إرجاع بدلا من 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)

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

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

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

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

نعم. من Frammar File.:

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

ملاحظة عند الاستخدام:

لاحظ أن كل شيء if يجب أن يتبع مع 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 يجب تقييم مرتين مع الاستخدام أعلاه. يمكن أن تحد من التكرار إذا كان مجرد متغير محلي. ومع ذلك، فإن المصطلحة المشتركة والأداء المؤدي لهذه الاستخدام الحالة هي استخدام orسلوك الاختصار:

expression1 or expression2

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

محاكاة المشغل الثغرية الثعبان.

علي سبيل المثال

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

انتاج:

'b greater than a'

يمكنك ان تفعلها :-

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

مثال:-

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

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


النتائج :- إذا كان الشرط صحيحا exp_1 يتم تنفيذ exp_2 آخر.

ملحوظة :- 0، لا شيء، كاذبة، مفرقة، إفراغ، تقييم كاذبة. وأية بيانات بخلاف 0 يقيم إلى True.

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

إذا أصبحت الحالة [شرط] "صحيحا"، فسيتم تقييم Expression_1 ولكن ليس التعبير_2. إذا كنا "و" شيء مع 0 (صفر)، فإن النتيجة ستكون دائما فاسلي .so في العبارة أدناه،

0 and exp

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

في

1 or exp

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

ولكن في حالة

True and exp1 or exp2

لن يتم تقييم EPP2 التعبير الثاني منذ True and exp1 سيكون صحيحا عندما exp1 ليس خطأ.

وبالمثل في

False and exp1 or exp2

لن يتم تقييم Expression EXP1 نظرا لأن FALSE يعادل الكتابة 0 والقيام "و" مع 0 سيكون 0 نفسه ولكن بعد EXP1 نظرا لاستخدامه "أو" يستخدمه، فسيقوم بتقييم Expression Exp2 بعد "أو".


ملحوظة:- لا يمكن استخدام هذا النوع من المتفرعة باستخدام "أو" و "و" فقط عندما يكون لدى Expression_1 قيمة الحقيقة للخطأ (أو 0 أو لا شيء أو إفراغي [] أو إفراغ ".) منذ ذلك الحين إذا أصبح التعبير_1 خطأ، ثم سيتم تقييم Expression_2 بسبب وجود "أو" بين Exp_1 و Exp_2.

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

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

يتيح المشغل الشرطي الثغرية ببساطة اختبار حالة في سطر واحد استبدال Multiline IF- وإخراج رمز رمز.

بناء الجملة :

ON_TRUE] إذا [التعبير] آخر [on_false

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

# 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

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

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

, ، يصبح:

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

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

a if condition else b

ما عليك سوى حفظ هذا الهرم إذا كنت تواجه مشكلة في التذكر:

     condition
  if           else
a                   b 

نعم، لدى Python مشغل Ternary، إليك بناء الجملة ومثالا مثالا لإظهار نفسه :)

#[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")

العديد من لغات البرمجة المستمدة من C عادة ما يكون بناء الجملة التالي للمشغل الشرطي التيرني:

<condition> ? <expression1> : <expression2>

في البداية، Python بمنقوع دأكياس Fأو لIFE (أعني Guido Van Rossum، بالطبع) رفضه (بأنه أسلوب غير بيثوني)، لأنه من الصعب للغاية فهم الأشخاص الذين لا يستخدمون C لغة. أيضا، علامة القولون : يحتوي بالفعل العديد من الاستخدامات في Python. وبعد بعد بيب 308. تم قبوله، Python تلقى أخيرا التعبير الشرطي الاختصار الخاص به (ما نستخدمه الآن):

<expression1> if <condition> else <expression2>

لذلك، أولا يقيم الشرط. إذا عاد True, التعبير 1. سيتم تقييمها لإعطاء النتيجة، وإلا التعبير 2 سيتم تقييمها. بسبب تقييم كسول ميكانيكا - سيتم تنفيذ تعبير واحد فقط.

فيما يلي بعض الأمثلة (سيتم تقييم الشروط من اليسار إلى اليمين):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

يمكن للسلاسل من مشغلي الثغرية في السلسلة:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

ما يلي هو نفسه السابق:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

أتمنى أن يساعدك هذا.

واحدة من بدائل لبثون التعبير الشرطي ما يلي:

{True:"yes", False:"no"}[boolean]

التي لديها امتداد لطيف التالي:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

أقصر بقايا أدلة:

("no", "yes")[boolean]

ولكن لا يوجد بديل إذا كنت ترغب في تجنب تقييم كليهما yes() و no() في التالي:

yes() if [condition] else no()

إذا تم تعريف المتغير وتريد التحقق مما إذا كان لديه قيمة يمكنك فقط 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

طريقة أنيقة إلى سلسلة مشغلي متعددة:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top