21 Pytanie: Czy Python ma trójwarstwowego operatora warunkowego?

pytanie utworzone w Sat, Mar 23, 2019 12:00 AM

Jeśli Python nie ma trójwarstwowego operatora warunkowego, czy można go symulować za pomocą innych konstrukcji językowych?

    
5269
  1. Chociaż Pythony starsze niż 2.5 powoli dryfują do historii, oto lista starych trików trójskładnikowych przed 2.5: " Python Idioms ", wyszukaj tekst„ Warunkowe wyrażenie ”. Wikipedia jest również bardzo pomocna Ж :-)
    2011-05-26 00: 48: 06Z
  2. W oficjalnej dokumentacji Pythona 3.0, do której odwołuje się powyższy komentarz, jest to nazywane „wyrażeniami warunkowymi” i jest bardzo kryptycznie zdefiniowane. Ta dokumentacja nie zawiera nawet terminu „trójskładnikowego”, więc trudno byłoby znaleźć ją za pośrednictwem Google, chyba że wiesz dokładnie, czego szukać. Dokumentacja wersji 2 jest nieco bardziej pomocna i zawiera link do „PEP 308” , który zawiera wiele interesujących kontekstów historycznych do tego pytania.
    2013-01-10 05: 57: 30Z
  3. "ternary" (posiadający trzy wejścia) jest następczą właściwością tej impelmentacji, a nie właściwością definiującą pojęcie. np .: SQL ma case [...] { when ... then ...} [ else ... ] end dla podobnego efektu, ale nie ma trójskładności.
    2014-12-15 21: 14: 24Z
  4. także ISO /IEC 9899 (standard języka programowania C) w sekcji 6.5.15 nazywa go "operatorem warunkowym"
    2014-12-15 21: 20: 22Z
  5. Wikipedia dokładnie to opisuje w artykule " ?: ".
    2016-06-09 08: 11: 03Z
21 odpowiedzi                              21                         

Tak, to było dodano w wersji 2.5. Składnia wyrażenia to:

 
a if condition else b

Pierwszy condition jest oceniany, a następnie dokładnie jeden z a lub b jest oceniany i zwracany na podstawie Boolean wartość condition. Jeśli condition ocenia na True, to a jest oceniane i zwracane, ale b jest ignorowane, lub gdy b jest oceniane i zwracane, ale a jest ignorowane.

Pozwala to na zwarcie, ponieważ gdy condition jest prawdziwe, tylko a jest oceniane, a b nie jest w ogóle oceniane, ale gdy condition jest fałszywe, tylko b jest oceniane, a a nie jest w ogóle oceniane.

Na przykład:

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

Zauważ, że warunkowe to wyrażenie , a nie instrukcja . Oznacza to, że nie możesz używać instrukcji przypisania ani pass ani innych instrukcji w warunkowym wyrażeniu :

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

Możesz jednak użyć wyrażeń warunkowych, aby przypisać zmienną w ten sposób:

 
x = a if True else b

Pomyśl o wyrażeniu warunkowym jako o przełączaniu między dwiema wartościami. Jest to bardzo przydatne, gdy znajdujesz się w sytuacji „jednej wartości lub innej”, ale nie robi nic więcej.

Jeśli chcesz użyć wyciągów, musisz użyć zwykłej instrukcji if zamiast warunkowego wyrażenia .


Pamiętaj, że niektórzy Pythonistas nie są zadowoleni z kilku powodów:

  • Kolejność argumentów różni się od kolejności klasycznego operatora trójskładnikowego condition ? a : b z wielu innych języków (takich jakjak C, C ++, Go, Perl, Ruby, Java, Javascript itp.), co może prowadzić do błędów, gdy używają go osoby nie znające „zaskakującego” zachowania Pythona (mogą odwrócić kolejność argumentów).
  • Niektórzy uważają, że jest „nieporęczna”, ponieważ jest sprzeczna z normalnym przepływem myśli (myśląc najpierw o stanie, a potem o efektach).
  • Powody stylistyczne. (Chociaż „inline if” może być naprawdę użyteczny, a skrypt bardziej zwięzły, to naprawdę komplikuje kod)

Jeśli masz problemy z zapamiętaniem kolejności, pamiętaj, że podczas czytania na głos (prawie) mówisz, co masz na myśli. Na przykład x = 4 if b > 8 else 9 jest odczytywany na głos jako x will be 4 if b is greater than 8 otherwise 9.

Oficjalna dokumentacja:

2019-05-18 10: 26: 57Z
  1. Kolejność może wydawać się dziwna dla koderów, jednak f(x) = |x| = x if x > 0 else -x brzmi bardzo naturalnie dla matematyków. W większości przypadków możesz to również zrozumieć jako A, z wyjątkiem sytuacji, gdy zamiast tego C powinieneś zrobić B ...
    2016-01-25 15: 07: 08Z
  2. Uważaj na kolejność operacji podczas korzystania z tego. Na przykład linia z = 3 + x if x < y else y. Jeśli x=2 i y=1, możesz się spodziewać, że przyniesie 4, ale faktycznie przyniesie 1. z = 3 + (x if x > y else y) to poprawne użycie.
    2016-03-06 09: 23: 11Z
  3. Chodziło o to, że jeśli chcesz wykonać dodatkowe oceny po warunkowe jest oceniane, np. dodając wartość do wyniku, będziesz albo należy dodać dodatkowe wyrażenie do obu stron (z = 3 + x if x < y else 3 + y) lub zgrupować warunkowe (z = 3 + (x if x < y else y) lub z = (x if x < y else y) + 3)
    2016-04-15 00: 36: 05Z
  4. co, jeśli istnieje wiele warunków?
    2017-05-26 15: 31: 44Z
  5. @ MrGeek, widzę, co masz na myśli, więc zasadniczo zagnieżdżanie operacji: `" foo ", jeśli Bool else (" bar ", jeśli Bool inaczej" foobar " ) `
    2017-08-11 00: 04: 32Z

Możesz zaindeksować krotkę:

 
(falseValue, trueValue)[test]

test musi zwrócić True lub False .
Bezpieczniej byłoby zawsze zaimplementować go jako:

 
(falseValue, trueValue)[test == True]

lub możesz użyć wbudowanego bool() aby zapewnić wartość boolowską :

 
(falseValue, trueValue)[bool(<expression>)]
    
689
2015-10-17 07: 35: 10Z
  1. Zauważ, że ten zawsze oblicza wszystko, podczas gdy konstrukcja if /else ocenia tylko wygrywające wyrażenie.
    2011-02-04 02: 25: 24Z
  2. (lambda: print("a"), lambda: print("b"))[test==true]()
    2012-03-08 19: 31: 48Z
  3. Należy zauważyć, że to, co znajduje się w [] s, może być dowolnym wyrażeniem. Ponadto, dla bezpieczeństwa, możesz jawnie przetestować prawdziwość, pisząc [bool(<expression>)]. Funkcja bool() istnieje od wersji 2.2.1.
    2012-05-31 18: 20: 15Z
  4. Świetnie nadaje się do gry w golfa z kodem, a nie do kodu. Chociaż tak się do tego przyzwyczaiłem, że go używamczasami dla zwięzłości podczas robienia czegoś oczywistego, jak wybieranie między dwiema stałymi łańcuchowymi.
    2014-12-05 17: 52: 12Z
  5. Wykonałem podobną sztuczkę - tylko raz lub dwa razy, ale zrobiłem to - indeksując do słownika True i False jako klucze: {True:trueValue, False:falseValue}[test] I don nie wiem, czy jest to mniej efektywne, ale przynajmniej pozwala uniknąć całej „eleganckiej” i „brzydkiej” debaty. Nie ma dwuznaczności, że masz do czynienia z logiczną, a nie int.
    2016-03-01 18: 43: 37Z

W wersjach wcześniejszych niż 2.5 istnieje sztuczka:

 
[expression] and [on_true] or [on_false]

Może dać błędne wyniki, gdy on_true  ma wartość false boolean. 1
Chociaż ma to tę zaletę, że ocenia wyrażenia od lewej do prawej, co moim zdaniem jest jaśniejsze.

1. Czy istnieje odpowiednik C's??: ”Operator trójskładnikowy?

    
289
2014-01-13 07: 16: 48Z
  1. Rozwiązaniem jest użycie (test i [true_value] lub [false_value]) [0], co pozwala uniknąć tej pułapki.
    2009-10-21 15: 33: 59Z
  2. Operator Ternary zwykle wykonuje się szybciej (czasami o 10-25%).
    2014-01-13 07: 52: 08Z
  3. @ volcano Czy masz dla mnie źródło?
    2014-08-05 12: 30: 33Z
  4. 2018-03-19 20: 59: 54Z

<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
    
200
2019-05-15 15: 03: 41Z
  1. Jaka jest różnica między tą a najlepszą odpowiedzią?
    2010-05-27 07: 59: 27Z
  2. Ten podkreśla główny cel operatora trójskładnikowego: wybór wartości. Pokazuje również, że więcej niż jeden trójskładnik może być połączony w jedno wyrażenie.
    2010-10-04 21: 14: 21Z
  3. @ Craig, zgadzam się, ale warto też wiedzieć, co się stanie, gdy nie będzie nawiasów. W prawdziwym kodzie ja też chciałbym wstawiać wyraźne pareny.
    2014-12-01 21: 30: 51Z
  4. W jakiś sposób mogę zrozumieć to lepiej niż najlepsza odpowiedź.
    2018-03-23 ​​05: 46: 05Z

Z dokumentacja :

  

Wyrażenia warunkowe (czasami nazywane „operatorem trójskładnikowym”) mają najniższy priorytet wszystkich operacji Pythona.

     

Wyrażenie x if C else y najpierw ocenia warunek, C ( nie x ); jeśli C jest prawdą, sprawdzany jest x a jego wartość jest zwracana; w przeciwnym razie y jest obliczane i zwracana jest jego wartość.

     

Zobacz PEP 308 po więcej szczegółów na temat wyrażeń warunkowych.

Nowy od wersji 2.5.

    
125
2015-10-17 07: 43: 53Z

Operator dla warunkowego wyrażenia w Pythonie został dodany w 2006 roku jako część Python Enhancement Propozycja 308 . Jego forma różni się od zwykłego operatora ?: i jest:

 
<expression1> if <condition> else <expression2>

co jest równoważne:

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

Oto przykład:

 
result = x if a > b else y

Inna składnia, której można użyć (zgodna z wersjami przed 2.5):

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

gdzie operandy są leniwie oceniane .

Innym sposobem jest indeksowanie krotki (która nie jest zgodna z operatorem warunkowym większości innych języków):

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

lub jawnie skonstruowany słownik:

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

Inną (mniej niezawodną), ale prostszą metodą jest użycie and i or operatorów:

 
result = (a > b) and x or y

jednak to nie zadziała, jeśli x będzie False.

Możliwym obejściem jest utworzenie x i y list lub krotek w następujący sposób:

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

lub:

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

Jeśli pracujesz ze słownikami, zamiast używać warunku trójskładnikowego, możesz skorzystać z get(key, default) , na przykład:

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

Źródło: ?: w Pythonie z Wikipedii

    
95
2017-08-07 14: 22: 32Z
  1. result = {1: x, 0: y}[a > b] to kolejny możliwy wariant (True i False są w rzeczywistości liczbami całkowitymi o wartościach 1 i 0)
    2019-02-09 18: 07: 40Z

Niestety

 
(falseValue, trueValue)[test]
Rozwiązanie

nie ma zachowania zwarciowego; zatem zarówno falseValue, jak i trueValue są oceniane niezależnie od stanu. Może to być suboptymalne lub nawet błędne (tzn. Zarówno trueValue, jak i falseValue mogą być metodami i mieć efekty uboczne).

Jednym z rozwiązań byłoby

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

(wykonanie opóźnione, dopóki zwycięzca nie jest znany;)), ale wprowadza niespójność między obiektami wywoływalnymi i nieobliczalnymi. Ponadto nie rozwiązuje przypadku, gdy używasz właściwości.

I tak się dzieje - wybór między trzema wspomnianymi rozwiązaniami jest kompromisem między posiadaniem funkcji zwarcia, używaniem co najmniej Зythona 2.5 (IMHO już nie jest problemem) i nie jest podatny na „trueValue -ocenia-do -false „błędy.

    
86
2019-05-09 09: 45: 33Z
  1. Podczas gdy krotka sztuczki lambdas działa, zajmuje ona około 3x tak długo, jak operator trójskładnikowy. Prawdopodobnie będzie to rozsądny pomysł, jeśli może zastąpić długi łańcuch if else if.
    2018-10-11 17: 34: 51Z

Operator trójskładnikowy w różnych językach programowania

Po prostu próbuję pokazać jakąś ważną różnicę w ternary operator między kilkoma językami programowania.

  

Ternary Operator w JavaScript

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

Ternary Operator w Ruby

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

Operator trójskładnikowy w Scala

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

Operator trójskładnikowy w programowaniu R

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

Operator trójskładnikowy w Pythonie

 
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
    
56
2019-01-26 14: 05: 18Z
  1. 2017-02-15 23: 08: 50Z
  2. Ruby działa również z a = true ? 1 : 0
    2017-05-15 17: 50: 10Z
  3. "Teraz możesz zobaczyć piękno języka Pythona. Jest bardzo czytelny i możliwy do utrzymania." Nie widzę znaczenia tego zdania ani tego, jak demonstruje to składnia operatora trójskładnikowego.
    2017-12-08 15: 38: 17Z
  4. Może brzmieć to na opinię; ale zasadniczo mówi, że składnia Pythona może być zrozumiana przez osobę, która nigdy nie widziała operatora trójskładnikowego, podczas gdy bardzo niewiele osób zrozumie bardziej zwykłą składnię, chyba że powiedziano jej najpierw, co to znaczy.
    2018-01-10 17: 12: 28Z
  5. Algol68: a = .if. .prawdziwe. .następnie. 1 .else. 0 .fi. Może to być również wyrażone jako = (. True. | 1 | 0) Jak zwykle Algol68 jest ulepszeniem w stosunku do jego następców.
    2018-06-17 12: 55: 29Z

Dla Pythona 2.5 i nowszych istnieje specyficzna składnia:

 
[on_true] if [cond] else [on_false]

W starszych Pythonach operator trójwymiarowy nie jest zaimplementowany, ale można go symulować.

 
cond and on_true or on_false

Istnieje jednak potencjalny problem, który, jeśli cond ocenia na True, a on_true na False, zwraca on_false zamiast on_true. Jeśli chcesz tego zachowania, metoda jest OK, w przeciwnym razie użyj:

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

, który można zawinąć:

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

i użyty w ten sposób:

 
q(cond, on_true, on_false)

Jest kompatybilny ze wszystkimi wersjami Pythona.

    
55
2012-04-25 12: 02: 06Z
  1. Zachowanie nie jest identyczne - q("blob", on_true, on_false) zwraca on_false, podczas gdy on_true if cond else on_false zwraca on_true. Rozwiązaniem jest zastąpienie cond cond is not None w tych przypadkach, chociaż nie jest to idealne rozwiązanie.
    2012-09-26 09: 09: 29Z
  2. Dlaczego nie bool(cond) zamiast cond is True? Pierwsza sprawdza prawdziwość cond, druga sprawdza równość wskaźnika z obiektem True. Jak podkreśla @AndrewCecil, "blob" jest prawdą, ale is not True.
    2013-11-11 16: 11: 06Z
  3. Wow, to wygląda naprawdę hacky! :) Technicznie możesz nawet napisać [on_false, on_True][cond is True], aby wyrażenie stało się krótsze.
    2014-02-24 11: 51: 08Z
  4. W tej odpowiedzi nie ma zwarcia. Jeśli on_true i on_false są drogie, wywołanie jest złą odpowiedzią.
    2019-03-28 14: 08: 20Z

Często możesz znaleźć

 
cond and on_true or on_false

ale to prowadzi do problemu, gdy on_true == 0

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

gdzie można oczekiwać od zwykłego operatora trójskładnikowego tego wyniku

 
>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
    
35
2013-01-14 15: 56: 09Z
  

Czy Python ma trójwarstwowego operatora warunkowego?

Tak. Z plik gramatyki :

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

Interesującą częścią jest:

 
or_test ['if' or_test 'else' test]

Zatem trójwarstwowa operacja warunkowa ma postać:

 
expression1 if expression2 else expression3

expression3 będzie leniwie oceniany (czyli oceniany tylko wtedy, gdy expression2 jest fałszem w kontekście boolowskim). Ze względu na definicję rekurencyjną można je łączyć łańcuchowo w nieskończoność (choć może to oznaczać zły styl).

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

Notatka dotycząca użycia:

Zauważ, że każdy if musi być przestrzegany z else. Ludzie uczący się wyrażeń na listach i wyrażeń generatora mogą uznać, że jest to trudna lekcja do nauczenia się - poniższe zasady nie będą działać, ponieważ Python oczekuje trzeciego wyrażenia dla innego:

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

, która podnosi SyntaxError: invalid syntax. Tak więc powyższe jest albo niekompletną logiką (być może użytkownik spodziewa się braku operacji w fałszywym warunku), albo zamierzeniem jest użycie wyrażenia2 jako filtru - zauważa, że ​​poniżej jest legalny Python:

 
[expression1 for element in iterable if expression2]

expression2 działa jako filtr do rozumienia listy i jest nie operatorem warunkowym trójskładnikowym.

Alternatywna składnia dla bardziej wąskiego przypadku:

Może się okazać, że trochę bolesne będzie napisanie następującego tekstu:

 
expression1 if expression1 else expression2

expression1 będzie musiał zostać dwukrotnie oceniony przy użyciu powyższego użycia. Może ograniczyć nadmiarowość, jeśli jest to po prostu zmienna lokalna. Jednak powszechnym i skutecznym idiomem Pythonicznym dla tego przypadku jest użycie skrótów or:

 
expression1 or expression2

, który jest równoważny w semantyce. Zauważ, że niektóre przewodniki stylów mogą ograniczać to użycie ze względu na przejrzystość - pakuje wiele znaczeń w bardzo małą składnię.

    
28
2016-08-08 18: 56: 31Z
  1. expression1 or expression2 jest podobny i ma takie same wady /pozytywy jak expression1 || expression2 w javascript
    2016-02-18 13: 05: 59Z
  2. Dzięki, @selurvedu - może być mylące, dopóki nie zrozumiesz. Nauczyłem się na własnej skórze, więc twoja droga może nie być tak trudna. ;) Użycie, jeśli bez innego, na końcu wyrażenia generatora lub zrozumienia listy spowoduje filtrowanie iterowalne. Z przodu jest potrójna operacja warunkowa i wymaga innej. Pozdrawiam !!
    2016-05-27 04: 37: 39Z
  3. @ AaronHall Chociaż użycie metasyntactic expressionN dla wszystkich instancji jest spójne, może być łatwiej zrozumieć z nazewnictwem, które odróżnia warunkowe wyrażenie testowe od dwóch wyrażeń wynikowych; np. result1 if condition else result2. Jest to szczególnie widoczne podczas zagnieżdżania (aka łańcuchowania): result1 if condition1 else result2 if condition2 else result3. Zobacz, o ile lepiej to czyta w ten sposób?
    2019-01-26 14: 12: 47Z
  4. @ tchrist dzięki za recenzję - jeśli spojrzysz na historię wersji, ten post ma obecnie dwie wersje. Większość moich innych odpowiedzi, zwłaszcza tych najlepszych, była ponownie odwiedzana wielokrotnie. Ta odpowiedź nigdy nie zwróci mojej uwagi, ponieważ status wiki społeczności nie daje mi żadnej oceny treści, więc nigdy nie widzę na niej żadnych głosów. Ponieważ tak naprawdę nie mam teraz czasu na edycję, frog wie, kiedy w przyszłości ponownie zwróci moją uwagę. Widzę, że edytowałeś najlepszą odpowiedź, więc możesz pożyczyć /zacytować mój materiał z tego posta w tym (i zacytować mnie, jeśli apropos!)
    2019-01-26 18: 24: 21Z

Symulowanie operatora trójargumentowego Pythona.

Na przykład

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

wyjście:

 
'b greater than a'
    
17
2013-11-20 10: 44: 12Z
  1. Dlaczego nie po prostu result = (y, x)[a < b] Dlaczego używasz funkcji lambda ?
    2013-12-27 05: 50: 06Z
  2. @ GrijeshChauhan Ponieważ na wyrażeniach „komplikowanych”, np. sol. w przypadku wywołania funkcji itp., zostanie to wykonane w obu przypadkach. To może nie być pożądane.
    2014-02-13 08: 14: 33Z

możesz to zrobić: -

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

Przykład: -

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

Spowoduje to wydrukowanie „nieparzyste”, jeśli liczba jest nieparzysta lub „parzysta”, jeśli liczba jest parzysta.


Wynik: - jeśli warunek jest prawdziwy, exp_1 jest wykonywane, inaczej wykonywane jest exp_2.

Uwaga: - 0, None, False, emptylist, emptyString ocenia jako False. I wszelkie dane inne niż 0 oceniają na True.

Oto jak to działa:

jeśli warunek [warunek] stanie się „Prawda”, wtedy wyrażenie_1 zostanie ocenione, ale nie będzie wyrażeniem_2. Jeśli „i” coś z 0 (zero), wynik zawsze będzie fasle. Tak w poniższym zestawieniu,

 
0 and exp

Wyrażenie exp nie zostanie w ogóle ocenione, ponieważ „i” z 0 zawsze będzie miało wartość zero i nie ma potrzeby oceniania wyrażenia. Tak działa sam kompilator we wszystkich językach.

W

 
1 or exp

wyrażenie exp nie zostanie w ogóle ocenione, ponieważ „lub” z 1 zawsze będzie równe 1. Więc nie będzie kłopotać się oceną wyrażenia exp, ponieważ wynik i tak będzie 1. (metody optymalizacji kompilatora).

Ale w przypadku

 
True and exp1 or exp2

Drugie wyrażenie exp2 nie zostanie ocenione, ponieważ True and exp1 byłoby Prawdą, gdy exp1 nie jest fałszywe.

Podobnie w

 
False and exp1 or exp2

Wyrażenie exp1 nie zostanie ocenione, ponieważ False jest równoważne zapisaniu 0, a wykonanie „i” za pomocą 0 będzie równe 0, ale po exp1, ponieważ użyto „lub”, oceni wyrażenie exp2 po „lub”.


Uwaga: - ten rodzaj rozgałęziania za pomocą „lub” i „i” może być użyty tylko wtedy, gdy wyrażenie_1 nie ma wartości Prawda False (lub 0 lub Brak lub pusta lista [] lub emptystring ''.) ponieważ jeśli wyrażenie_1 stanie się Fałszem, to wyrażenie_2 zostanie ocenione z powodu obecności „lub” między exp_1 i exp_2.

Jeśli nadal chcesz, aby działał we wszystkich przypadkach, niezależnie od tego, jakie są wartości prawdy exp_1 i exp_2, zrób to: -

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

    
15
2017-08-20 07: 48: 54Z
  1. Jeśli chcesz użyć tego w kontekście x = [condition] and ([expression_1] or 1) or [expression_2] i expression_1 do fałszu, x będzie 1, a nie expression_1. Użyj zaakceptowanej odpowiedzi.
    2017-10-20 06: 37: 01Z

Trójwarstwowy operator warunkowy pozwala po prostu przetestować warunek w pojedynczej linii, zastępując multilinię, jeśli-jeszcze, czyniąc kod zwartym.

Składnia:

  

[on_true] if [wyrażenie] else [on_false]

1- Prosta metoda użycia operatora trójskładnikowego:

 
# 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- Bezpośrednia metoda używania krotek, słownika i 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- Operator trójargumentowy może być zapisany jako zagnieżdżony jeśli-in:

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

Powyższe podejście można zapisać jako:

 
# 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
    
14
2018-04-04 14: 02: 17Z
  1. Zauważ, że operator trójskładnikowy jest mniejszy (w pamięci) i szybszy niż zagnieżdżony jeśli. Ponadto, twój zagnieżdżony if-else w rzeczywistości nie jest przepisywany przez operatora trójskładnikowego i będzie produkował różne dane wyjściowe dla wybranych wartości a i b (szczególnie, jeśli jest to typ implementujący dziwną metodę __ne__).
    2018-10-11 17: 28: 46Z

Więcej napiwku niż odpowiedzi (nie trzeba powtarzać tego oczywistego przez setny czas), ale czasami używam go jako skrótu do onelinera w takich konstrukcjach:

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

staje się:

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

Niektóre (wiele :) może nie wyglądać na unpythonic (nawet ruby-ish :), ale osobiście uważam to za bardziej naturalne - tj. jak normalnie byś to wyraził, a także bardziej atrakcyjne wizualnie w dużych blokach kod.

    
12
2016-05-23 19: 16: 26Z
  1. Wolę print( 'yes' if conditionX else 'nah' ) od odpowiedzi. :-)
    2017-08-20 06: 07: 17Z
  2. To znaczy, jeśli chcesz print() w obu przypadkach - i wygląda to trochę bardziej pytonicznie, muszę przyznać :) Ale co jeśli wyrażenia /funkcje nie są taki sam - jak print('yes') if conditionX else True - aby uzyskać print() tylko w prawdzie conditionX
    2017-10-26 11: 40: 17Z
  3. Aby dodać do uwagi Frederick99, kolejnym powodem, dla którego należy unikać print('yes') if conditionX else print('nah'), jest to, że daje on SyntaxError w Pythonie2.
    2018-10-21 21: 51: 29Z
  4. Jedynym powodem, dla którego podaje błąd składniowy, jest to, że w Pythonie 2 druk jest instrukcją - print "yes", podczas gdy w Pythonie 3 jest funkcją - print("yes"). Można to rozwiązać, używając go jako oświadczenia lub lepiej - from future import print_function.
    2018-10-22 04: 09: 00Z
 
a if condition else b

Zapamiętaj tę piramidę, jeśli masz problem z zapamiętaniem:

 
     condition
  if           else
a                   b 
    
9
2018-12-06 14: 45: 27Z

TAK, python ma operatora trójskładnikowego, oto składnia i przykładowy kod do zademonstrowania tego samego :)

 
#[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")
    
4
2018-10-21 20: 46: 34Z
  1. Dodałem przykład z jednym wierszem, aby sprawdzić, który numer jest duży, aby go dalej rozwinąć
    2018-10-21 20: 45: 54Z
  2. print naprawdę nie jest dobrym wyborem, ponieważ da to SyntaxError w Pythonie2.
    2018-10-21 21: 52: 56Z
  3. @ Thierry Lathuille Tutaj użyłem funkcji print () bez instrukcji print, funkcja print jest dla Pythona 3, a instrukcja print dla Pythona 2
    2018-10-21 21: 54: 21Z
  4. Pytanie zostało już zadane na SO, po prostu spróbuj z Pythonem 2, a zobaczysz sam. 'print (' hello ') jest doskonale poprawną składnią w Pythonie 2.7, ale sposób jego analizy powoduje, że powyższy kod rzuca błąd SyntaxError.
    2018-10-21 21: 58: 23Z
  5. Co jest poprawnego, powiedz
    2018-10-21 22: 00: 52Z

Wiele języków programowania wywodzących się z C zazwyczaj ma następującą składnię trójskładnikowego operatora warunkowego:

 
<condition> ? <expression1> : <expression2>
  

Początkowo Python B odpowiedni D ictator F lub L ife (mam na myśli Guido van Rossum , oczywiście) odrzucił go (jako styl nie-Pythoniczny), ponieważ jest to dość trudne do zrozumienia dla osób nie używających języka C. Ponadto dwukropek : ma już wiele zastosowań w Python. Po zatwierdzeniu PEP 308 Python w końcu otrzymał własne wyrażenie warunkowe skrótu (co używamy teraz):

 
<expression1> if <condition> else <expression2>

Więc najpierw ocenia warunek. Jeśli zwróci True, wyrażenie1 zostanie ocenione, aby dać wynik, w przeciwnym razie wyrażenie2 zostanie ocenione. Dzięki mechanice Leniwa ocena - zostanie wykonane tylko jedno wyrażenie.

Oto kilka przykładów (warunki wźle oceniany od lewej do prawej):

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

# Result is 'High'

Operatory trójskładnikowe można łączyć szeregowo:

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

# Result is 'Normal'

Następujący jest taki sam jak poprzedni:

 
pressure = 5

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

# Result is 'Normal'

Mam nadzieję, że to pomoże.

    
4
2019-01-04 22: 02: 14Z

Jedna z alternatyw dla warunkowego wyrażenia jest następujące:

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

, który ma następujące ładne rozszerzenie:

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

Pozostaje najkrótsza alternatywa:

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

ale nie ma alternatywy, jeśli chcesz uniknąć oceny zarówno yes(), jak i no() w następujących przypadkach:

 
yes() if [condition] else no()
    
3
2019-02-09 18: 23: 18Z

Dobry sposób na połączenie wielu operatorów:

 
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

    
0
2019-05-12 13: 03: 48Z

jeśli zmienna jest zdefiniowana i chcesz sprawdzić, czy ma wartość, możesz tylko 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)

wyświetli

 
no Input
no Input
no Input
hello
['Hello']
True
    
- 1
2018-04-26 16: 22: 58Z
  1. Chociaż jest przydatny do podobnych problemów, nie jest to warunkowy trójskładnik. Działa w celu zastąpienia x if x else y, ale nie x if z else y.
    2018-10-11 17: 13: 50Z
źródło umieszczone tutaj