Чи в Python є потрійний умовний оператор?


6042

Якщо Python не має потрійного умовного оператора, чи можна імітувати його за допомогою інших мовних конструкцій?


149
В офіційній документації Python 3.0, на яку йдеться в коментарі вище, це позначається як "conditional_expressions" і дуже криптично визначено. Ця документація навіть не включає термін "потрійний", тому вам важко буде знайти його через Google, якщо ви точно не знали, що шукати. Документація версії 2 є дещо кориснішою і включає посилання на "PEP 308" , що містить багато цікавого історичного контексту, пов'язаного з цим питанням.
nobar

26
"потрійний" (з трьома входами) є наслідком властивості цієї імпементації, а не визначальною властивістю концепції. наприклад: SQL має case [...] { when ... then ...} [ else ... ] endподібний ефект, але зовсім не потрійний.
користувач313114

10
також ISO / IEC 9899 (стандарт мови програмування C) розділ 6.5.15 називає його "умовним оператором"
користувач313114

9
Вікіпедія це докладно висвітлює у статті " ?: ".
HelloGoodbye

9
У роки з коментаря Нобара документація умовного вираження була оновлена, щоб сказати Умовні вирази (іноді їх називають "потрійним оператором") ...
Скотт Мартін

Відповіді:


7040

Так, його додано у версії 2.5. Синтаксис виразу:

a if condition else b

Спочатку conditionоцінюється, потім рівно один із них aабо bоцінюється та повертається на основі булевого значення condition. Якщо conditionоцінюється до True, то aвін оцінюється і повертається, але bігнорується, інакше коли bоцінюється і повертається, але aігнорується.

Це дозволяє коротке замикання, тому що коли conditiontrue aє, то оцінюється і bне оцінюється взагалі, а коли conditionfalse 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потрійного оператора з багатьох інших мов (таких як C, C ++, Go, Perl, Ruby, Java, Javascript тощо), що може призвести до помилок, коли люди не знайомі з Python's " дивно "поведінка використовуйте його (вони можуть змінити порядок аргументів).
  • Деякі вважають це "непростим", оскільки це суперечить нормальному потоку думок (спочатку думаючи про стан, а потім про наслідки).
  • Стилістичні причини. (Хоча "вбудований if" може бути дуже корисним і зробити ваш сценарій більш стислим, він дійсно ускладнює ваш код)

Якщо у вас виникають проблеми з запам'ятовуванням замовлення, то пам’ятайте, що, читаючи вголос, ви (майже) говорите, що маєте на увазі. Наприклад, x = 4 if b > 8 else 9читається вголос як x will be 4 if b is greater than 8 otherwise 9.

Офіційна документація:


268
Порядок може здатися дивним для кодерів, проте f(x) = |x| = x if x > 0 else -xматематикам звучить дуже природно. Ви також можете зрозуміти це як A в більшості випадків, за винятком випадків, коли C тоді вам слід зробити B замість цього ...
йота

120
Будьте обережні з порядком операцій при використанні цього. Наприклад, рядок z = 3 + x if x < y else y. Якщо x=2і y=1, то, можливо, ви очікуєте, що вийде 4, але це насправді вихід 1. z = 3 + (x if x > y else y)Це правильне використання.
Кал Зекдор

11
Сенс полягав у тому, що якщо ви хочете виконати додаткові оцінки після того, як умовне оцінюється, як-от додавання значення в результат, вам або потрібно буде додати додатковий вираз в обидві сторони ( 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)
Кал Зекдор

4
@MrGeek, я бачу, що ти маєш на увазі, тому ти в основному вкладеш операції: `" foo ", якщо Bool else (" bar ", якщо Bool else" foobar ")`
Dimesio

3
Програмістам потрібна точна правильна постановка навіть більше, ніж математику, тому що в математиці завжди вдаються до основних понять. Переконливим аргументом є оператор%, наслідування способу використання "mod" в математиці було б катастрофою. Так що ні, я не приймаю ваших аргументів. Це як дотримання імперських загонів. Groetjes Albert
Альберт ван дер Хорст

795

Ви можете проіндексувати в кортеж:

(falseValue, trueValue)[test]

testпотрібно повернути Істинне чи Неправдиве .
Це може бути безпечніше завжди виконувати його як:

(falseValue, trueValue)[test == True]

або ви можете використовувати вбудований bool()для забезпечення булевого значення:

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

589
Зауважте, що цей завжди оцінює все, тоді як конструкція if / else оцінює лише виграшне вираз.
SilverbackNet

117
(lambda: print("a"), lambda: print("b"))[test==true]()
Дастін Гец

15
Слід зазначити, що те, що знаходиться в межах []s, може бути довільним виразом. Також для безпеки ви можете явно перевірити справжність, написавши [bool(<expression>)]. bool()Функція була приблизно з v2.2.1.
мартіно

12
Я зробив подібний трюк - лише один чи два рази, але зробив це - індексувавши словник із клавішами Trueта Falseяк ключі: {True:trueValue, False:falseValue}[test] я не знаю, чи це менш ефективно, але принаймні уникає цілого "елегантний" проти "потворний" дебат. Не існує двозначності, що ти маєш справу з булевим, а не з int.
JDM


338

Для версій до 2,5 є хитрість:

[expression] and [on_true] or [on_false]

Він може давати неправильні результати, коли on_true має помилкове булеве значення. 1
Хоча це має користь оцінювати вирази зліва направо, що на мою думку зрозуміліше.

1. Чи існує еквівалент термінального оператора "?:"?


67
Засіб полягає у використанні (тест і [true_value] або [false_value]) [0], що дозволяє уникнути цієї пастки.
ThomasH

5
Термінальний оператор зазвичай виконує швидше (іноді на 10-25%).
вулкан

7
@volcano У вас є джерело для мене?
OrangeTux

4
@OrangeTux Ось розібраний код . Використання запропонованого методом ThomasH було б ще повільніше.
mbomb007

265

<expression 1> if <condition> else <expression 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

83
Цей підкреслює основний намір потрійного оператора: вибір значення. Це також показує, що більш ніж один трійник може бути пов'язаний в один вираз.
Рой Тінкер

6
@Craig, я згоден, але також корисно знати, що буде, коли немає дужок. У реальний код я теж схильний вставляти явні паролі.
Джон Кумбс

158

З документації :

Умовні вирази (іноді їх називають "потрійним оператором") мають найнижчий пріоритет з усіх операцій Python.

Вираз x if C else yспочатку оцінює умову, C ( не x ); якщо C є істинним, оцінюється x і повертається його значення; в іншому випадку оцінюється y і повертається його значення.

Див. PEP 308 для отримання більш детальної інформації про умовні вирази.

Новий з версії 2.5.


120

Оператор для умовного вираження в Python був доданий у 2006 році як частина пропозиції 308 щодо вдосконалення Python . Його форма відрізняється від звичайного ?:оператора і це:

<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списки чи кортежі, як зазначено в наступному:

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

Джерело: ?: У Python у Wikipedia


1
result = {1: x, 0: y}[a > b]є ще один можливий варіант ( Trueа Falseнасправді цілі числа зі значеннями 1і 0)
Уолтер Трос

98

На жаль,

(falseValue, trueValue)[test]

рішення не має короткого замикання; таким чином і те falseValueй інше trueValueоцінюється незалежно від умови. Це може бути неоптимальним або навіть баггі (тобто обидва trueValueі falseValueможуть бути методами та мати побічні ефекти).

Одним з рішень цього було б

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

(виконання затягується до тих пір, поки переможець не буде відомий;)), але він вносить невідповідність між об'єктами, що дзвонять, і які не можуть викликати. Крім того, це не вирішує випадок при використанні властивостей.

І тому історія іде - вибір між трьома згаданими рішеннями є компромісом між тим, що має функцію короткого замикання, використовуючи принаймні Zython 2.5 (IMHO вже не проблема) і не схильний до trueValueпомилок " -evaluates-to-false" .


2
Хоча тюк лямбдаського трюку працює, це займає приблизно в 3 рази більше, ніж потрійний оператор. Цілком імовірна ідея, якщо вона може замінити довгий ланцюг if else if.
Перкінс

72

Ternary Operator на різних мовах програмування

Тут я просто намагаюся показати якусь важливу різницю ternary operatorміж парою мов програмування.

Термінальний оператор у 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

Термінальний оператор в Python

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


5
Це може здатися впевнено; але це, по суті, говорить, що це синтаксис Python, ймовірно, буде зрозумілий людині, яка ніколи не бачила потрійного оператора, тоді як дуже мало людей зрозуміють звичайніший синтаксис, якщо їм спочатку не сказали, що це означає.
fralau

1
Algol68: a = .if. .тру. .тоді. 1 .else. 0 .fi. Це може бути виражено також a = (. Вірно. | 1 | 0) Як зазвичай Algol68 - це поліпшення порівняно з його наступниками.
Альберт ван дер Хорст

63

Для Python 2.5 і новіших є специфічний синтаксис:

[on_true] if [cond] else [on_false]

У старих пітонах потрійний оператор не реалізований, але можливо його моделювати.

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)

Він сумісний з усіма версіями Python.


2
Поведінка не тотожна - q("blob", on_true, on_false)повертається on_false, тоді як on_true if cond else on_falseповертається on_true. Обійти це можна замінити condз cond is not Noneв цих випадках, незважаючи на те, що не є ідеальним рішенням.

5
Чому б не bool(cond)замість цього cond is True? Перший перевіряє правдивість cond, другий перевіряє на рівність вказівника з Trueоб'єктом. Як підкреслив @AndrewCecil, "blob"це правда, але це is not True.
Йонас Кёлкер

Нічого собі, це виглядає справді хакітно! :) Технічно можна навіть писати, [on_false, on_True][cond is True]щоб вираз став коротшим.
Арсеній

У цій відповіді немає короткого замикання. Якщо on_true та on_false дорого називати, це погана відповідь.
Хакер

44

Ви можете часто знайти

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

38

Чи в Python є потрійний умовний оператор?

Так. З граматичного файлу :

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. Люди, що вивчають розуміння списків та вирази генераторів, можуть вважати це важким уроком - наступне не вийде, оскільки Python очікує третього виразу для іншого:

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

який піднімає a SyntaxError: invalid syntax. Отже, вищезазначене є або неповною частиною логіки (можливо, користувач очікує, що в помилковому стані не працює), або те, що може бути призначено, це використовувати express2 як фільтр - зазначає, що наступне є законним Python:

[expression1 for element in iterable if expression2]

expression2працює як фільтр для розуміння списку, і не є потрійним умовним оператором.

Альтернативний синтаксис для більш вузького випадку:

Вам може здатися дещо болісним написати наступне:

expression1 if expression1 else expression2

expression1доведеться оцінювати двічі при використанні вище. Це може обмежити надмірність, якщо це просто локальна змінна. Тим не менш, загальна і ефективна пітонічна ідіома для цього випадку використання полягає у використанні скорочувальної orповедінки:

expression1 or expression2

що рівнозначно в семантиці. Зауважте, що деякі довідники стилів можуть обмежувати це використання на основі ясності - він містить багато сенсу в синтаксис дуже мало.


1
expression1 or expression2схожий і з тими ж недоліками / позитивом, що і expression1 || expression2у javascript
JSDBroughton

1
Дякую, @selurvedu - це може заплутати, поки ти не зрозумієш це. Я навчився важкого шляху, тому твій шлях може бути не таким важким. ;) Використовуючи, якщо без іншого, в кінці виразу генератора або розуміння списку буде фільтруватися ітерабельний. Попереду, це потрійна умовна операція, і вимагає іншого. Ура !!
Зал Аарона

@AaronHall Незважаючи на те, що метасинтаксичне використання expressionNдля всіх примірників є послідовним, це може бути легше зрозуміти з називанням, яке відрізняло умовний тестовий вираз від двох виразних виразів; наприклад, result1 if condition else result2. Це особливо очевидно , коли вкладеності (ака ланцюжка): result1 if condition1 else result2 if condition2 else result3. Бачите, наскільки краще це читається таким чином?
tchrist

@tchrist дякую за відгук - якщо ви подивитесь на історію редагувань, ця публікація наразі має дві редакції. Більшість моїх інших відповідей, особливо найкращі, переглядалися знову і знову. Ця відповідь ніколи не привертає моєї уваги, оскільки статус вікі спільноти не надає мені ніякої заслуги за вміст, і тому я ніколи не бачу жодного голосу за нього. Оскільки я зараз не маю часу на редагування цього питання, жаба знає, коли в майбутньому вона мені знову припаде до уваги. Я можу бачити, що ви відредагували головну відповідь, тому сміливо позичайте / цитуйте мої матеріали з цієї публікації в цій публікації (і цитуйте мене, якщо підходить!)
Аарон Холл

23

Імітація потрійного оператора пітона.

Наприклад

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'

Чому б не просто result = (y, x)[a < b]Чому ви використовуєте lambdaфункцію ?
Гріеш Чаухан

5
@GrijeshChauhan Оскільки у "складених" виразах, наприклад із залученням функції виклику тощо, це буде виконуватися в обох випадках. Цього можна не захотіти.
glglgl

20

Термінальний умовний оператор просто дозволяє перевірити стан в одному рядку, замінивши багаторядковий, якщо ще зробити код компактним.

Синтаксис:

[on_true] if [вираз] else [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- Прямий метод використання кортежів, словника та лямбда:

# 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

1
Зауважте, що потрійний оператор менший (у пам'яті) і швидший, ніж вкладений, якщо. Крім того, ваше вкладене if-elseфактично не є перезаписом потрійного оператора, і дасть різний вихід для вибраних значень a і b (зокрема, якщо це тип, який реалізує дивний __ne__метод).
Перкінс

19

Ви можете це зробити:

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

Приклад: -

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

Це буде друкувати "непарне", якщо число непарне або "парне", якщо число парне.


Результат: - Якщо умова вірна, виконується exp_1, ще виконується exp_2.

Примітка: - 0, None, False, emptylist, emptyString оцінюється як False. І будь-які дані, окрім 0, оцінюють як True.

Ось як це працює:

якщо умова [умова] стає "Істинною", тоді вираження_1 буде оцінено, але не вираз_2. Якщо ми "і" щось з 0 (нуль), результат завжди буде незрівнянним. Отже, у наведеному нижче твердженні,

0 and exp

Вираз exp взагалі не буде оцінюватися, оскільки "і" з 0 завжди будуть дорівнювати нулю, і немає необхідності оцінювати вираз. Так працює сам компілятор на всіх мовах.

В

1 or exp

вираз exp взагалі не буде оцінюватися, оскільки "або" з 1 завжди буде 1. Отже, він не буде турбуватися оцінювати вираз exp, оскільки результат все одно буде 1. (методи оптимізації компілятора).

Але у випадку

True and exp1 or exp2

Другий вираз exp2 не буде оцінено, оскільки True and exp1було б істинно, коли exp1 не є хибним.

Аналогічно в

False and exp1 or exp2

Вираз exp1 не буде оцінюватися, оскільки False еквівалентний написанню 0 і виконанню "і" з 0 буде 0, але після використання exp1, оскільки "або" використовується, він оцінить вираз exp2 після "або".


Примітка: - Цей тип розгалуження за допомогою "або" і "і" може використовуватися лише тоді, коли у виразу_1 немає значення Істини Неправдивого (або 0 або Немає, або емплітиста [] або порожнього рядка ".), Оскільки якщо вираз_1 стає Неправильно, тоді вираз_2 буде оцінено через наявність "або" між exp_1 та exp_2.

Якщо ви все ще хочете змусити його працювати у всіх випадках незалежно від значень правди exp_1 та exp_2, зробіть це:

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


Якщо ви хочете використовувати це в контексті x = [condition] and ([expression_1] or 1) or [expression_2]та expression_1оцінювати як хибне, xбуде 1, ні expression_1. Використовуйте прийняту відповідь.
травень

18

Більше підказки, ніж відповіді (не потрібно повторювати очевидне для того часу), але я іноді використовую це як ярлик для одного ряду в таких конструкціях:

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

, стає:

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

Деякі (багато :) можуть нахмуритися на це як непітонічне (навіть, рубіно-іш :), але я особисто вважаю це більш природним - тобто, як би ви це виразили нормально, плюс трохи більш візуально привабливим у великих блоках коду.


5
Я віддаю перевагу print( 'yes' if conditionX else 'nah' )своїй відповіді. :-)
frederick99

Тобто, якщо ви хочете print()в обох випадках - і це виглядає дещо пітонічніше, я мушу визнати :) Але що робити, якщо вирази / функції не однакові - як print('yes') if conditionX else True- щоб отримати print()єдиний у трютіconditionX
Тодор Мінаков,

Щоб додати до зауваження Frederick99, ще одна причина уникнення print('yes') if conditionX else print('nah')- це те, що воно дає SyntaxError в Python2.
Тьєррі Латуй

Єдина причина, в якій виникає синтаксична помилка, полягає в тому, що в Python 2 друкується вислів - print "yes", а в Python 3 - це функція - print("yes"). Це можна вирішити, використовуючи його як заяву, а краще - from future import print_function.
Тодор Мінаков

18
a if condition else b

Просто запам’ятайте цю піраміду, якщо у вас виникли проблеми з запам'ятовуванням:

     condition
  if           else
a                   b 

14

Одна з альтернатив умовному вираженню Пітона

"yes" if boolean else "no"

наступне:

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

яке має таке приємне розширення:

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

Залишається найкоротша альтернатива:

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

але альтернативи цьому немає

yes() if boolean else no()

якщо ви хочете уникати оцінювання yes() і no() , тому що в

(no(), yes())[boolean]  # bad

обидва no()і yes()оцінюються.


10

Багато мов програмування, що походять із Cзвичайно, мають такий синтаксис термінального умовного оператора:

<condition> ? <expression1> : <expression2>

Спочатку Python B поступливий D ictator F або L ife (я маю на увазі, Ґвідо ван Россум, звичайно) відкинув це (як непітонічний стиль), оскільки це досить важко зрозуміти людям, які не звикли до Cмови. Також знак двокрапки :вже має багато застосувань Python. Після того, як PEP 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'

Сподіваюсь, це допомагає.


10

Як уже відповіли, так, у python є потрійний оператор:

<expression 1> if <condition> else <expression 2>

Додаткова інформація:

Якщо <expression 1>це умова, ви можете використовувати оцінку короткого замикання :

a = True
b = False

# Instead of this:
x = a if a else b

# You could use Short-cirquit evaluation:
x = a or b

PS: Звичайно, оцінка короткого замикання не є потрійним оператором, але часто тернар використовується в тих випадках, коли короткого замикання буде достатньо.


1
Підвищення short-circuitоцінки.
CodeIt

7

ТАК, у python є потрійний оператор, ось синтаксис та приклад коду, щоб продемонструвати те саме :)

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

Я додав приклад заяви в одному рядку, щоб перевірити, яке число є великим, щоб його детальніше
розглянути

1
printнасправді не є вдалим вибором, оскільки це дасть SyntaxError в Python2.
Тьєррі Латуй

@Thierry Lathuille тут я використовував функцію print (), а не друковану заяву, функція друку призначена для Python 3, тоді як операція друку - для Python 2
PythonLover

Питання вже задали на SO, просто спробуйте його з Python 2, і ви самі переконаєтесь. 'print (' привіт ') - це абсолютно вірний синтаксис в Python 2.7, але те, як він розбирається, змушує ваш код вище кидати SyntaxError.
Тьєррі Латуй

2

Python має потрійну форму для виконання завдань; однак, може бути навіть коротша форма, про яку люди повинні знати.

Дуже часто потрібно присвоювати змінній те чи інше значення залежно від умови.

>>> li1 = None
>>> li2 = [1, 2, 3]
>>> 
>>> if li1:
...     a = li1
... else:
...     a = li2
...     
>>> a
[1, 2, 3]

^ Це довга форма виконання таких завдань.

Нижче наведено потрійну форму. Але це не самий складний спосіб - див. Останній приклад.

>>> a = li1 if li1 else li2
>>> 
>>> a
[1, 2, 3]
>>> 

З Python ви можете просто використовувати orдля альтернативних завдань.

>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Вищезазначене працює, оскільки li1є, Noneі interp трактує це як помилкове в логічних виразах. Потім інтерп рухається далі і оцінює другий вираз, якого немає, Noneі це не порожній список - тому він присвоюється а.

Це також працює з порожніми списками. Наприклад, якщо ви хочете призначити, у aякому списку є елементи.

>>> li1 = []
>>> li2 = [1, 2, 3]
>>> 
>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Знаючи це, ви можете просто робити такі завдання, коли стикаєтесь з ними. Це також працює з рядками та іншими ітерабелями. Ви можете призначити aбудь-який рядок не порожній.

>>> s1 = ''
>>> s2 = 'hello world'
>>> 
>>> a = s1 or s2
>>> 
>>> a
'hello world'
>>> 

Мені завжди подобався синтаксис C ternary, але Python робить це на крок далі!

Я розумію, що деякі можуть сказати, що це не гарний стилістичний вибір, оскільки він покладається на механіку, яка не відразу зрозуміла всім розробникам. Я особисто не згоден з цією точкою зору. Python - насичена синтаксисом мова з безліччю ідіоматичних хитрощів, які не відразу зрозумілі для даблера. Але чим більше ви дізнаєтесь і зрозумієте механіку базової системи, тим більше ви її оціните.


1

Інші відповіді правильно говорять про потрійний оператор Python. Я хотів би доповнити, зазначивши сценарій, для якого часто використовується потрійний оператор, але для якого є краща ідіома. Це сценарій використання значення за замовчуванням.

Припустимо, ми хочемо використовувати option_valueзі значенням за замовчуванням, якщо воно не встановлено:

run_algorithm(option_value if option_value is not None else 10)

або просто

run_algorithm(option_value if option_value else 10)

Однак все краще рішення - просто написати

run_algorithm(option_value or 10)

-2

якщо змінна визначена, і ви хочете перевірити, чи має вона значення, ви можете просто 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

1
Хоча це корисно для подібних проблем, це не є потрійним умовом. Він працює на заміну x if x else y, але ні x if z else y.
Перкінс

-2

Акуратний спосіб пов’язати кілька операторів:

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

-2

Я вважаю громіздким синтаксисом python за замовчуванням val = a if cond else b, тому іноді роблю це:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

Звичайно, у нього є недолік завжди оцінювати обидві сторони (a і b), але синтаксис мені зрозуміліший


Це здається вдвічі більшим за обсяг роботи, більше використання оперативної пам’яті та більш заплутане, ніж простіша val = a if cond else bзаява.
їсть їжу

-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

він може бути вкладений як ваша потреба. удачі

**

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.