Jeśli Python nie ma trójskładnikowego operatora warunkowego, czy można go symulować przy użyciu innych konstrukcji języka?
python
operators
ternary-operator
conditional-operator
poświęcony
źródło
źródło
case [...] { when ... then ...} [ else ... ] end
podobny efekt, ale wcale nie jest trójskładnikowy.Odpowiedzi:
Tak, został dodany w wersji 2.5. Składnia wyrażenia to:
Najpierw
condition
jest obliczany, a następnie dokładnie jeden z nicha
lubb
jest oceniany i zwracany na podstawie wartości logicznejcondition
. Jeślicondition
ocenia toTrue
, toa
jest oceniane i zwracane, aleb
jest ignorowane, lub kiedyb
jest oceniane i zwracane, alea
jest ignorowane.Pozwala to na zwarcie, ponieważ gdy
condition
jest prawdziwe tylkoa
jest oceniana ib
nie jest oceniana w ogóle, ale jeślicondition
jest fałszywe tylkob
jest oceniana ia
nie jest oceniana w ogóle.Na przykład:
Pamiętaj, że warunkowe są wyrażeniem , a nie wyrażeniem . Oznacza to, że nie można używać instrukcji przypisania
pass
ani innych instrukcji w wyrażeniu warunkowym :Możesz jednak użyć wyrażeń warunkowych, aby przypisać zmienną w następujący sposób:
Pomyśl o wyrażeniu warunkowym jako przełączaniu między dwiema wartościami. Jest to bardzo przydatne, gdy znajdujesz się w sytuacji „jednej lub innej wartości”, ale nie robi wiele więcej.
Jeśli potrzebujesz użyć instrukcji, musisz użyć normalnej
if
instrukcji zamiast wyrażenia warunkowego .Pamiętaj, że niektórzy Pythoniści patrzą na to z dezaprobatą z kilku powodów:
condition ? a : b
operatora trójskładnikowego w wielu innych językach (takich jak C, C ++, Go, Perl, Ruby, Java, JavaScript itp.), Co może prowadzić do błędów, gdy ludzie nie znają Pythona „ zaskakujące "użyj go (mogą odwrócić kolejność argumentów).if
” może być naprawdę przydatna i sprawia, że skrypt jest bardziej zwięzły, to naprawdę komplikuje kod)Jeśli masz problemy z zapamiętaniem kolejności, pamiętaj, że czytając na głos, (prawie) mówisz, co masz na myśli. Na przykład
x = 4 if b > 8 else 9
jest czytany na głos jakox will be 4 if b is greater than 8 otherwise 9
.Oficjalna dokumentacja:
źródło
f(x) = |x| = x if x > 0 else -x
dla matematyków brzmi to bardzo naturalnie. Możesz również zrozumieć to tak, jak A w większości przypadków, z wyjątkiem sytuacji, gdy C to powinieneś zrobić B zamiast tego ...z = 3 + x if x < y else y
. Jeślix=2
iy=1
, możesz oczekiwać, że da to 4, ale tak naprawdę da 1.z = 3 + (x if x > y else y)
to prawidłowe użycie.z = 3 + x if x < y else 3 + y
) lub zgrupować warunek (z = 3 + (x if x < y else y)
lubz = (x if x < y else y) + 3
)Możesz indeksować do krotki:
test
musi zwrócić wartość Prawda lub Fałsz .Bezpieczniej jest zawsze go wdrożyć, ponieważ:
lub możesz użyć wbudowanego,
bool()
aby zapewnić wartość logiczną :źródło
(lambda: print("a"), lambda: print("b"))[test==true]()
[]
literach, może być dowolnym wyrażeniem. Ponadto, dla bezpieczeństwa możesz wyraźnie przetestować prawdziwość, pisząc[bool(<expression>)]
. Tabool()
funkcja jest dostępna od wersji 2.2.1.True
iFalse
jako:{True:trueValue, False:falseValue}[test]
Nie wiem, czy jest to mniej wydajne, ale przynajmniej unika całości debata „elegancka” a „brzydka”. Nie ma wątpliwości, że masz do czynienia z wartością logiczną zamiast int.W przypadku wersji wcześniejszych niż 2.5 istnieje sztuczka:
Może dawać błędne wyniki, gdy
on_true
ma fałszywą wartość boolowską. 1Chociaż ma tę zaletę, że ocenia wyrażenia od lewej do prawej, co moim zdaniem jest wyraźniejsze.
1. Czy istnieje odpowiednik operatora trójskładnikowego „?”: „?
źródło
<expression 1> if <condition> else <expression 2>
źródło
Z dokumentacji :
Nowość od wersji 2.5.
źródło
Operator wyrażenia warunkowego w języku Python został dodany w 2006 r. Jako część propozycji ulepszenia języka Python 308 . Jego forma różni się od zwykłego
?:
operatora i jest:co jest równoważne z:
Oto przykład:
Inna składnia, której można użyć (kompatybilna z wersjami wcześniejszymi niż 2.5):
gdzie operandy są leniwie oceniane .
Innym sposobem jest indeksowanie krotki (co nie jest zgodne z operatorem warunkowym większości innych języków):
lub jawnie skonstruowany słownik:
Inną (mniej niezawodną), ale prostszą metodą jest użycie
and
ior
operatory:jednak to nie zadziała, jeśli
x
byłobyFalse
.Możliwym obejściem jest wykonanie
x
iy
wyświetlenie list lub krotek w następujący sposób:lub:
Jeśli pracujesz ze słownikami, zamiast trójkowego warunku, możesz
get(key, default)
na przykład skorzystać z :Źródło: ?: W Python na Wikipedii
źródło
result = {1: x, 0: y}[a > b]
jest innym możliwym wariantem (True
iFalse
faktycznie są liczbami całkowitymi z wartościami1
i0
)Niestety
rozwiązanie nie ma zwarć; więc zarówno
falseValue
itrueValue
są oceniane niezależnie od warunków. To może być panującymi lub nawet buggy (czyli zarównotrueValue
ifalseValue
może być metody i mają skutki uboczne).Jednym z takich rozwiązań byłoby
(wykonanie opóźnione do momentu poznania zwycięzcy;)), ale wprowadza niespójność między obiektami, które można wywoływać, a obiektami, których nie można wywołać. Ponadto nie rozwiązuje problemu przy korzystaniu z właściwości.
I tak oto historia - wybór pomiędzy 3 wymienionymi rozwiązaniami jest kompromisem między posiadaniem funkcji zwarcia, używaniem co najmniej honython 2.5 (IMHO już nie stanowi problemu) i niepodatnością na błędy „
trueValue
-szacowania-do-fałszowania” .źródło
if else if
.Operator trójskładnikowy w różnych językach programowania
Tutaj próbuję tylko pokazać ważną różnicę
ternary operator
między kilkoma językami programowania.źródło
Dla Python 2.5 i nowszych istnieje specjalna składnia:
W starszych pytonach operator trójskładnikowy nie jest zaimplementowany, ale można go zasymulować.
Istnieje jednak potencjalny problem, który jeśli zostanie
cond
ocenionyTrue
ion_true
oceni,False
toon_false
zostanie zwrócony zamiaston_true
. Jeśli chcesz mieć takie zachowanie, metoda jest OK, w przeciwnym razie użyj tego:które można owinąć:
i używał w ten sposób:
Jest kompatybilny ze wszystkimi wersjami Pythona.
źródło
q("blob", on_true, on_false)
zwracaon_false
, natomiaston_true if cond else on_false
zwracaon_true
. Rozwiązaniem jest zastąpieniecond
zecond is not None
w tych przypadkach, mimo że nie jest to idealne rozwiązanie.bool(cond)
zamiastcond is True
? Pierwszy sprawdza prawdziwośćcond
, drugi sprawdza równość wskaźnika zTrue
obiektem. Jak podkreśla @AndrewCecil,"blob"
jest to prawda, ale tak jestis not True
.[on_false, on_True][cond is True]
więc wyrażenie staje się krótsze.Często możesz znaleźć
ale prowadzi to do problemu, gdy on_true == 0
gdzie można oczekiwać tego od normalnego operatora trójskładnikowego
źródło
Tak. Z pliku gramatyki :
Część zainteresowania to:
Tak więc trójskładnikowa operacja warunkowa ma postać:
expression3
będzie leniwie oceniany (to znaczy oceniany tylko wtedy, gdyexpression2
jest fałszywy w kontekście logicznym). Ze względu na definicję rekurencyjną można je łączyć w nieskończoność (choć może to uważać za zły styl).Uwaga dotycząca użytkowania:
Zauważ, że po każdym
if
musi nastąpić znakelse
. Dla osób uczących się ze zrozumieniem list i wyrażeń generatora może to być trudna lekcja - poniższe czynności nie będą działać, ponieważ Python oczekuje trzeciego wyrażenia dla innej osoby:co 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 stanie), albo może być zamierzone użycie wyrażenia2 jako filtru - zauważa, że następujące jest legalne Python:expression2
działa jako filtr do zrozumienia listy i nie jest trójskładnikowym operatorem warunkowym.Alternatywna składnia dla wąskiego przypadku:
Może być trochę bolesne napisać następujące rzeczy:
expression1
będzie musiał zostać oceniony dwukrotnie przy powyższym użyciu. Może ograniczyć nadmiarowość, jeśli jest to po prostu zmienna lokalna. Jednak powszechnym i wydajnym idiomem Pythona dla tego przypadku użyciaor
jest zachowanie skrótu:co jest równoważne w semantyce. Zwróć uwagę, że niektóre przewodniki po stylach mogą ograniczać to użycie ze względu na przejrzystość - dodaje dużo znaczenia w bardzo małej składni.
źródło
expression1 or expression2
są podobne i mają takie same wady / zalety jakexpression1 || expression2
w javascriptexpressionN
we wszystkich instancjach jest spójne, łatwiejsze jest zrozumienie nazewnictwa, które odróżniało warunkowe wyrażenie testowe od dwóch wyrażeń wynikowych; npresult1 if condition else result2
. Jest to szczególnie widoczne, gdy gniazdowania (aka łańcuchowym)result1 if condition1 else result2 if condition2 else result3
. Widzisz, o ile lepiej to czyta w ten sposób?Symulacja trójskładnikowego języka python.
Na przykład
wynik:
źródło
result = (y, x)[a < b]
dlaczego korzystasz zlambda
funkcji ?Trójskładnikowy operator warunkowy pozwala po prostu przetestować warunek w jednym wierszu, zastępując multilinię, jeśli w przeciwnym razie kod jest zwarty.
Składnia:
1- Prosta metoda użycia operatora trójskładnikowego:
2- Bezpośrednia metoda używania krotek, słownika i lambda:
3- Operator trójskładnikowy można zapisać jako zagnieżdżony, jeśli:
Powyższe podejście można zapisać jako:
źródło
if-else
nie jest w rzeczywistości przepisywaniem operatora trójskładnikowego i będzie generować różne dane wyjściowe dla wybranych wartości aib (szczególnie jeśli jest to typ, który implementuje dziwną__ne__
metodę).możesz to zrobić :-
[condition] and [expression_1] or [expression_2] ;
Przykład:-
print(number%2 and "odd" or "even")
Spowoduje to wydrukowanie „nieparzystej”, jeśli liczba jest nieparzysta, lub „parzystej”, jeśli liczba jest parzysta.
Wynik: - Jeśli warunek jest spełniony, exp_1 jest wykonywane, w przeciwnym razie exp_2 jest wykonywane.
Uwaga :- 0, Brak, Fałsz, emptylist, emptyString ocenia się jako False. A wszelkie dane inne niż 0 mają wartość True.
Oto jak to działa:
jeśli warunek [warunek] stanie się „Prawdą”, wówczas wyrażenie_1 zostanie ocenione, ale nie wyrażenie_2. Jeśli my "i" coś z 0 (zero), wynik zawsze będzie fasle. Więc w poniższej instrukcji,
Wyrażenie exp nie będzie w ogóle oceniane, ponieważ „i” z 0 zawsze będzie oceniać na zero i nie ma potrzeby oceny wyrażenia. Tak działa sam kompilator we wszystkich językach.
W
wyrażenie exp nie będzie w ogóle oceniane, ponieważ „lub” z 1 zawsze będzie wynosić 1. Więc nie będzie kłopotać się oceną wyrażenia exp, ponieważ wynik i tak będzie wynosił 1. (metody optymalizacji kompilatora).
Ale w przypadku
Drugie wyrażenie exp2 nie będzie odtąd oceniane
True and exp1
byłoby prawdziwe, gdy exp1 nie jest fałszywe.Podobnie w
Wyrażenie exp1 nie zostanie ocenione, ponieważ False jest równoznaczne z zapisaniem 0 i zrobieniem „, a” z 0 byłoby 0, ale po exp1, ponieważ użyto „lub”, oceni wyrażenie exp2 po „lub”.
Uwaga: - Tego rodzaju rozgałęzienia za pomocą „lub” i „i” można użyć tylko wtedy, gdy wyrażenie_1 nie ma wartości Prawdy Fałsz (lub 0 lub Brak lub pusta lista [] lub pusty ciąg „”.), Ponieważ jeśli wyrażenie_1 staje się Fałsz, wówczas wyrażenie_2 zostanie ocenione ze względu na obecność „lub” między exp_1 a exp_2.
Jeśli nadal chcesz, aby działał we wszystkich przypadkach, niezależnie od wartości prawdy exp_1 i exp_2, wykonaj następujące czynności:
[condition] and ([expression_1] or 1) or [expression_2] ;
źródło
x = [condition] and ([expression_1] or 1) or [expression_2]
iexpression_1
FALSE,x
będzie1
, nieexpression_1
. Użyj zaakceptowanej odpowiedzi.Bardziej wskazówka niż odpowiedź (nie trzeba powtarzać oczywistości dla setnego czasu), ale czasami używam jej jako skrótu oneliner w takich konstrukcjach:
, staje się:
Niektórzy (wielu :) mogą się na to uważać za niepytonicznych (nawet rubinowych :), ale osobiście uważam, że jest to bardziej naturalne - tj. Jak wyrażasz to normalnie, a także trochę bardziej atrakcyjne wizualnie w dużych blokach kodu.
źródło
print( 'yes' if conditionX else 'nah' )
twoją odpowiedź. :-)print()
w obu przypadkach - i wygląda trochę bardziej pytonicznie, muszę przyznać :) Ale co, jeśli wyrażenia / funkcje nie są takie same - jakprint('yes') if conditionX else True
- aby uzyskaćprint()
jedyną prawdęconditionX
print('yes') if conditionX else print('nah')
jest to, że daje błąd SyntaxError w Python2.print "yes"
podczas gdy w Python 3 jest funkcją -print("yes")
. Można to rozwiązać, używając go jako instrukcji lub lepiej -from future import print_function
.Zapamiętaj tę piramidę, jeśli masz problemy z zapamiętaniem:
źródło
Jedna z alternatyw dla wyrażenia warunkowego Pythona
jest następujący:
który ma następujące ładne rozszerzenie:
Najkrótszą alternatywą pozostaje:
ale nie ma alternatywy dla
jeśli chcesz uniknąć oceny
yes()
ino()
, ponieważ wzarówno
no()
iyes()
są oceniane.źródło
Wiele języków programowania pochodzących z
C
zazwyczaj ma następującą składnię trójskładnikowego operatora warunkowego:Więc po pierwsze ocenia warunek. Jeśli zwróci
True
, wyrażenie1 zostanie ocenione, aby dać wynik, w przeciwnym razie wyrażenie2 zostanie ocenione. Ze względu na mechanikę Lazy Evaluation - zostanie wykonane tylko jedno wyrażenie.Oto kilka przykładów (warunki będą oceniane od lewej do prawej):
Operatory trójskładnikowe można łączyć szeregowo:
Poniższy jest taki sam jak poprzedni:
Mam nadzieję że to pomoże.
źródło
Jak już odpowiedziano, tak, w pythonie jest operator trójskładnikowy:
Dodatkowe informacje:
Jeśli
<expression 1>
jest to warunek, możesz użyć oceny krótkiego obwodu :PS: Oczywiście ocena zwarcia nie jest operatorem trójskładnikowym, ale często trójskładnik jest używany w przypadkach, w których zwarcie byłoby wystarczające.
źródło
short-circuit
oceną.TAK, python ma operator trójskładnikowy, oto składnia i przykładowy kod pokazujący to samo :)
źródło
print
naprawdę nie jest dobrym wyborem, ponieważ da to błąd SyntaxError w Python2.Python ma trójskładnikową formę przypisań; jednak może istnieć jeszcze krótsza forma, o której ludzie powinni wiedzieć.
Bardzo często konieczne jest przypisanie do zmiennej jednej lub innej wartości w zależności od warunku.
^ To długa forma wykonywania takich zadań.
Poniżej znajduje się trójskładnikowa forma. Ale to nie jest najbardziej zwięzły sposób - patrz ostatni przykład.
Dzięki Pythonowi możesz po prostu używać
or
do alternatywnych zadań.Powyższe działa odtąd
li1
jest,None
a interpretuje to jako False w wyrażeniach logicznych. Inter interpretuje następnie i ocenia drugie wyrażenie, które nie jestNone
i nie jest pustą listą - więc zostaje przypisane do.Działa to również z pustymi listami. Na przykład, jeśli chcesz przypisać
a
listę, która zawiera elementy.Wiedząc o tym, możesz po prostu wykonywać takie zadania za każdym razem, gdy je napotkasz. Działa to również z ciągami znaków i innymi iteracjami. Możesz przypisać
a
dowolny ciąg znaków, który nie jest pusty.Zawsze podobała mi się składnia trójskładnikowa C, ale Python idzie o krok dalej!
Rozumiem, że niektórzy mogą powiedzieć, że nie jest to dobry wybór stylistyczny, ponieważ opiera się na mechanice, która nie jest od razu widoczna dla wszystkich programistów. Ja osobiście nie zgadzam się z tym punktem widzenia. Python jest językiem bogatym w składnię i zawiera wiele idiomatycznych sztuczek, które nie są od razu widoczne dla dablera. Ale im więcej uczysz się i rozumiesz mechanikę bazowego systemu, tym bardziej go doceniasz.
źródło
Inne odpowiedzi poprawnie mówią o trójskładnikowym języku Python. Chciałbym uzupełnić, wymieniając scenariusz, w którym operator trójskładnikowy jest często używany, ale dla którego istnieje lepszy idiom. Jest to scenariusz użycia wartości domyślnej.
Załóżmy, że chcemy użyć
option_value
wartości domyślnej, jeśli nie jest ustawiona:lub po prostu
Jednak coraz lepszym rozwiązaniem jest po prostu pisanie
źródło
jeśli zmienna jest zdefiniowana i chcesz sprawdzić, czy ma wartość, możesz to zrobić
a or b
wyjdzie
źródło
x if x else y
, ale niex if z else y
.Świetny sposób na połączenie wielu operatorów:
źródło
Uciążliwa jest domyślna składnia Pythona
val = a if cond else b
, więc czasami robię to:Oczywiście ma to tę wadę, że zawsze ocenia obie strony (a i b), ale składnia jest dla mnie o wiele bardziej przejrzysta
źródło
val = a if cond else b
stwierdzenie.**
**
źródło