Python'un üçlü koşullu bir operatörü var mı?


6045

Python'un üçlü koşullu bir operatörü yoksa, başka bir dil yapısı kullanarak birini simüle etmek mümkün müdür?


149
Yukarıdaki bir yorumda atıfta bulunulan Python 3.0 resmi belgelerinde buna "koşullu_ifadeler" denir ve çok şifreli olarak tanımlanır. Bu dokümantasyonda "üçlü" terimi bile bulunmadığından, tam olarak neyi arayacağınızı bilmediğiniz sürece Google üzerinden bulmanız çok zor olurdu. Sürüm 2 belgelerine biraz daha yararlı ve bir bağlantı içerir "PEP 308" Bu soruya ilişkin ilginç tarihsel bağlam bir sürü içerir.
nobar

26
"üçlü" (üç girdiye sahip), kavramın tanımlayıcı bir özelliği değil, bu çimlenmenin bir sonucu niteliğindedir. ör: SQL case [...] { when ... then ...} [ else ... ] endbenzer bir etkiye sahiptir ancak hiç üçlü değildir.
user313114 15:14

10
ayrıca ISO / IEC 9899 (C programlama dili standardı) bölümü 6.5.15 "koşullu operatör" olarak adlandırır
user313114

9
Wikipedia bunu " ?: " Makalesinde ayrıntılı olarak ele almaktadır .
HelloGoodbye

9
Nobar'ın yorumundan bu yana geçen yıllar içinde koşullu ifade belgeleri Koşullu ifadeler (bazen "üçlü operatör" olarak adlandırılır)
Scott Martin

Yanıtlar:


7043

Evet, 2.5 sürümünde eklendi . İfade sözdizimi:

a if condition else b

Önce conditiondeğerlendirilir, sonra tam olarak biri aveya Boolean değeri besas alınarak değerlendirilir ve döndürülür . Olarak değerlendirilirse , o zaman değerlendirilir ve geri döndürülür, ancak yoksayılır veya başka bir zaman değerlendirilir ve döndürülür ancak yok sayılır.conditionconditionTrueabba

Bu, kısa devre yapılmasına izin verir, çünkü conditiondoğru olduğunda sadece adeğerlendirilir ve bhiç değerlendirilmez, ancak conditionyanlış olduğunda sadece bdeğerlendirilir ve ahiç değerlendirilmez.

Örneğin:

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

Conditionals bir olduğunu unutmayın ifadesi değil, bir açıklama . Bu, koşullu ifadede atama ifadelerini passveya diğer ifadeleri kullanamayacağınız anlamına gelir :

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

Ancak, aşağıdaki gibi bir değişken atamak için koşullu ifadeleri kullanabilirsiniz:

x = a if True else b

Koşullu ifadeyi iki değer arasında geçiş olarak düşünün. 'Bir değer ya da başka' bir durumda olduğunuzda çok faydalıdır, ancak başka bir şey yapmaz.

Eğer ifadeleri kullanmanız gerekirse, normal kullanmak zorunda if deyimi bir koşullu yerine ifadesi .


Bazı Pythonistalar tarafından çeşitli nedenlerle kaşlarını çattığını unutmayın:

  • Argümanların sırası, klasik condition ? a : büçlü operatörünkünden diğer birçok dilden (C, C ++, Go, Perl, Ruby, Java, Javascript, vb.) Farklıdır; bu, insanlar Python'un şaşırtıcı "davranış kullanmak (argüman sırasını tersine çevirebilir).
  • Bazıları bunu "hantal" bulur, çünkü normal düşünce akışına aykırıdır (önce durumu ve sonra etkileri düşünmek).
  • Stilistik nedenler. ('Satır içi if' gerçekten yararlı olabilir ve komut dosyanızı daha özlü hale getirse de , kodunuzu gerçekten karmaşık hale getirir)

Sırayı hatırlamakta sorun yaşıyorsanız, yüksek sesle okurken (neredeyse) ne demek istediğinizi söylediğinizi unutmayın. Örneğin, x = 4 if b > 8 else 9sesli olarak okunur x will be 4 if b is greater than 8 otherwise 9.

Resmi belgeler:


268
Düzen, kodlayıcılar için garip görünebilir, ancak f(x) = |x| = x if x > 0 else -xmatematikçiler için çok doğal görünüyor . Ayrıca çoğu durumda A gibi anlayabilirsiniz, C hariç, bunun yerine B yerine yapmalısınız ...
yota

121
Bunu kullanırken işlem sırasına dikkat edin. Örneğin, çizgi z = 3 + x if x < y else y. Eğer x=2ve y=1, 4 vermesini bekleyebilirsiniz, ancak aslında 1 verimi olacaktır z = 3 + (x if x > y else y). Doğru kullanımdır.
Kal Zekdor

11
Mesele şudur, koşullu değerlendirildikten sonra sonuca bir değer eklemek gibi ek değerlendirmeler yapmak istiyorsanız , ya her iki tarafa ek ifade eklemeniz ( z = 3 + x if x < y else 3 + y) ya da koşullu ( z = 3 + (x if x < y else y)veya z = (x if x < y else y) + 3)
gruplandırmanız gerekir

4
@MrGeek, ne demek istediğini anlıyorum, bu yüzden temelde işlemleri iç içe geçireceksin: Bool else ise "foo" (Bool else "foobar" ise "bar")
Dimesio

3
Programcılar matematikçiden daha doğru bir doğru formülasyona ihtiyaç duyarlar, çünkü matematikte her zaman altta yatan kavramlara bir çare vardır. İkna edici bir argüman% operatörü, matematikte "mod" un kullanılma şeklini taklit eden bir felaket olurdu. Yani hayır, tartışmanızı kabul etmiyorum. Emperyal birimlere bağlılık gibi. Groetjes Albert
Albert van der Horst

797

Bir dizine dizin oluşturabilirsiniz:

(falseValue, trueValue)[test]

testTrue veya False döndürmesi gerekiyor .
Her zaman şu şekilde uygulamak daha güvenli olabilir:

(falseValue, trueValue)[test == True]

veya yerleşik bool()bir Boole değeri sağlamak için kullanabilirsiniz :

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

590
Bunun her zaman her şeyi değerlendirdiğini, if / else yapısının ise yalnızca kazanan ifadeyi değerlendirdiğini unutmayın.
SilverbackNet

117
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz

15
Bu []s içinde olanların keyfi bir ifade olabileceği unutulmamalıdır. Ayrıca, güvenlik için yazarak gerçekliği açıkça test edebilirsiniz [bool(<expression>)]. bool()Fonksiyon v2.2.1 yana civarında olmuştur.
martineau

12
Benzer bir hile yaptım - sadece bir veya iki kez, ama bunu - bir sözlükle Trueve Falseanahtarları olarak endeksleyerek yaptım : {True:trueValue, False:falseValue}[test] Bunun daha az verimli olup olmadığını bilmiyorum, ama en azından bütünden kaçınıyor "zarif" ve "çirkin" tartışma. Bir int yerine bir boole ile uğraştığınız belirsizliği yoktur.
JDM


338

2.5'ten önceki sürümler için hile var:

[expression] and [on_true] or [on_false]

Yanlış on_true bir boole değeri olduğunda yanlış sonuçlar verebilir . 1
Her ne kadar benim görüşüme göre daha açık olan soldan sağa ifadeleri değerlendirme avantajına sahip olsa da.

1. C '”?:” Üçlü operatörün eşdeğeri var mı?


67
Çözüm, bu tuzağı önleyen (test ve [true_value] veya [false_value]) [0] kullanmaktır.
ThomasH

5
Üçlü operatör genellikle daha hızlı çalışır (bazen% 10-25 oranında).
volkan

7
@volcano Benim için kaynağın var mı?
OrangeTux

4
@OrangeTux İşte demonte kod . ThomasH'ın önerdiği yöntemi kullanarak daha yavaş olacaktır.
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
Bu, üçlü operatörün birincil amacını vurgular: değer seçimi. Aynı zamanda, birden fazla üçlü birlikte tek bir ifadeye zincirlenebileceğini göstermektedir.
Roy Tinker

6
@Craig, katılıyorum, ancak parantez olmadığında ne olacağını bilmek de yardımcı oluyor. Gerçek kod, ben de açık parens eklemek eğilimindedir.
Jon Coombs

159

Gönderen belgeler :

Koşullu ifadeler (bazen “üçlü operatör” olarak da adlandırılır) tüm Python işlemlerinde en düşük önceliğe sahiptir.

İfade x if C else yönce durumu değerlendirir, C ( x değil ); Eğer Cı- doğrudur, X değerlendirilir ve değeri geri döndürülür; aksi takdirde y değerlendirilir ve değeri döndürülür.

Koşullu ifadeler hakkında daha fazla bilgi için PEP 308'e bakınız .

Sürüm 2.5'ten beri yeni.


120

Python'da koşullu ifade için bir operatör, Python Geliştirme Önerisi 308'in bir parçası olarak 2006 yılında eklendi . Formu ortak ?:operatörden farklıdır ve:

<expression1> if <condition> else <expression2>

eşdeğer:

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

İşte bir örnek:

result = x if a > b else y

Kullanılabilecek başka bir sözdizimi (2.5'ten önceki sürümlerle uyumlu):

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

işlenenler tembel olarak değerlendirilir .

Başka bir yol, bir demet dizini (diğer birçok dilin koşullu işleciyle tutarlı olmayan) endekslemektir:

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

veya açıkça oluşturulmuş sözlük:

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

Başka (daha az güvenilir), ancak daha basit bir yöntem kullanmak andve oroperatörler:

result = (a > b) and x or y

ancak bu işe yaramazsa xolmaz False.

Olası bir geçici çözüm, aşağıdaki gibi yapılması xve ylistelendiği veya tuples edilmesidir:

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

veya:

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

Sözlüklerle çalışıyorsanız, üçlü koşullu kullanmak yerine aşağıdakilerden yararlanabilirsiniz get(key, default):

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

Kaynak: ?: Wikipedia'da Python'da


1
result = {1: x, 0: y}[a > b]başka bir olası varyanttır ( Trueve Falseaslında değerlerle tamsayıdır 1ve 0)
Walter Tross

98

Ne yazık ki

(falseValue, trueValue)[test]

çözümün kısa devre davranışı yoktur; böylece her ikisi de falseValueve trueValuekoşuldan bağımsız olarak değerlendirilir. Bu optimal-altı olabilir ya da arabası (yani her iki trueValueve falseValueyöntemler olabilir ve yan etkilere sahip olabilir).

Bunun bir çözümü

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

(icra kazanan bilinene kadar ertelenir;)), ancak çağrılabilir ve çağrılamaz nesneler arasında tutarsızlık getirir. Ayrıca, özellikleri kullanırken durumu çözmez.

Ve böylece hikaye devam ediyor - sözü edilen 3 çözüm arasından seçim yapmak, kısa devre özelliğine sahip olmak, en azından Зython 2.5 (artık IMHO artık bir sorun değil) kullanmak ve " trueValueyanlış değerlendirir" hatalarına eğilimli olmamak arasında bir denge .


2
Lambdas hilesi çalışırken, üçlü operatör yaklaşık 3 kat daha uzun sürer. Uzun bir zincirinin yerini alabiliyorsa, makul bir fikir olması muhtemeldir if else if.
Perkins

72

Farklı programlama dillerinde üçlü operatör

Burada sadece ternary operatorbirkaç programlama dili arasında bazı önemli farklar göstermeye çalışıyorum .

Javascript'teki üçlü operatör

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

Ruby'de üçlü operatör

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

Scala'daki üçlü operatör

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

R programında üçlü operatör

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

Python'da üçlü operatör

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


5
Görüşlü gibi gelebilir; ama esas olarak söylediği şey, Python sözdiziminin hiç üçlü bir operatör görmemiş bir kişi tarafından anlaşılması muhtemeldir, ancak çok az insan ilk önce ne anlama geldiğini söylemedikçe daha olağan sözdizimini anlayacaktır.
fralau

1
Algol68: a = .if. .doğru. .sonra. 1. başka. 0 .fi. Bu aynı zamanda a = (. True. | 1 | 0) olarak da ifade edilebilir. Algol68 her zamanki gibi halefleri üzerinde bir gelişmedir.
Albert van der Horst

63

Python 2.5 ve daha yeni sürümler için belirli bir sözdizimi vardır:

[on_true] if [cond] else [on_false]

Eski Pythons'ta üçlü bir operatör uygulanmaz, ancak simüle edilebilir.

cond and on_true or on_false

Gerçi, eğer olası bir sorun vardır condiçin değerlendirir Trueve on_truekarşı değerlendirir Falsesonra on_falseyerine döndürülür on_true. Bu davranışı istiyorsanız yöntem Tamam, aksi takdirde bunu kullanın:

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

hangi ile sarılabilir:

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

ve şu şekilde kullanılır:

q(cond, on_true, on_false)

Tüm Python sürümleriyle uyumludur.


2
Davranışı aynı değildir - q("blob", on_true, on_false)döner on_false, oysa on_true if cond else on_falsegetiri on_true. Bir geçici çözüm değiştirmektir condile cond is not Nonebu mükemmel bir çözüm olmasa da, bu gibi durumlarda.

5
Neden bool(cond)yerine cond is True? Birincisi doğruluğunu kontrol eder, condikincisi Truenesne ile işaretçi eşitliğini kontrol eder . @AndrewCecil tarafından vurgulandığı gibi "blob", doğrudur ama o is not True.
Jonas Kölker

Vay be, bu gerçekten çılgınca görünüyor! :) Teknik olarak, [on_false, on_True][cond is True]ifadenin kısalması için bile yazabilirsiniz .
Arseny

Bu cevapta kısa devre yok. On_true ve on_false'ı aramak pahalıysa, bu kötü bir cevaptır.
Hucker

44

Sıklıkla bulabilirsin

cond and on_true or on_false

ancak on_true == 0 olduğunda soruna yol açar

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

normal bir üçlü operatör beklediğiniz yerde bu sonuç

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1

38

Python'un üçlü koşullu bir operatörü var mı?

Evet. Gönderen dilbilgisi dosyası :

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

İlgilenilen kısım:

or_test ['if' or_test 'else' test]

Üçlü bir koşullu işlem şu şekildedir:

expression1 if expression2 else expression3

expression3tembel olarak değerlendirilecektir (yani yalnızca expression2boole bağlamında yanlışsa değerlendirilecektir ). Ve özyinelemeli tanım nedeniyle, süresiz olarak zincirleyebilirsiniz (kötü stil olarak kabul edilebilir.)

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

Kullanım hakkında bir not:

Her ifbiri bir ile takip edilmelidir else. Liste kavrayışlarını ve jeneratör ifadelerini öğrenen insanlar bunun öğrenilmesi zor bir ders olduğunu düşünebilir - Python başka bir üçüncü ifade beklediğinden aşağıdakiler işe yaramaz:

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

hangi a yükseltir SyntaxError: invalid syntax. Bu yüzden, ya tamamlanmamış bir mantık parçası (belki de kullanıcı yanlış durumda bir işlem yapılmasını beklemez) ya da amaçlanan ifade2'yi bir filtre olarak kullanmaktır - aşağıdakilerin yasal Python olduğuna dikkat edin:

[expression1 for element in iterable if expression2]

expression2Liste anlama için bir filtre olarak çalışır ve bir değil bir üçlü koşullu operatör.

Daha dar bir vaka için alternatif sözdizimi:

Aşağıdakileri yazmanın biraz acı verici olduğunu görebilirsiniz:

expression1 if expression1 else expression2

expression1yukarıdaki kullanımla birlikte iki kez değerlendirilmesi gerekecektir. Yalnızca yerel bir değişkense fazlalığı sınırlayabilir. Bununla birlikte, bu kullanım senaryosu için yaygın ve performanslı bir Pythonic deyim, orkısayol davranışını kullanmaktır:

expression1 or expression2

anlambilimde eşdeğerdir. Bazı stil kılavuzlarının bu kullanımı netlik temelinde sınırlayabileceğini unutmayın - çok az sözdizimine çok fazla anlam yükler.


1
expression1 or expression2expression1 || expression2javascript'teki benzer ve aynı dezavantajlar / pozitifler ile
JSDBroughton

1
Teşekkürler @selurvedu - düz olana kadar kafa karıştırıcı olabilir. Zor yoldan öğrendim, bu yüzden yolunuz o kadar zor olmayabilir. ;) Başka bir şey yoksa, bir jeneratör ifadesinin veya liste kavrayışının sonunda yinelenebilir filtrelendiğinde. Önde, üçlü bir koşullu işlemdir ve diğerini gerektirir. Alkış !!
Aaron Hall

@AaronHall expressionNTüm durumlar için metasyntaktik kullanımınız tutarlı olsa da, koşullu test ifadesini iki sonuç ifadesinden ayıran adlandırma ile anlaşılması daha kolay olabilir; ör result1 if condition else result2. (Zincirleme olarak da bilinir), yerleştirme sırasında, bu özellikle belirgindir: result1 if condition1 else result2 if condition2 else result3. Bunun bu şekilde ne kadar iyi okuduğunu görüyor musunuz?
tchrist

@tchrist inceleme için teşekkürler - düzeltme geçmişine bakarsanız, bu yayının şu anda iki düzeltmesi vardır. Diğer cevaplarımın çoğu, özellikle de en çok yanıtları tekrar tekrar tekrar ziyaret edildi. Bu cevap hiçbir zaman dikkatimi çekmedi çünkü topluluk wiki durumu bana içerik için hiç kredi vermiyor ve bu yüzden hiçbir zaman oy kullanmıyorum. Şu anda bu konuda bir düzenleme yapmak için gerçekten zamanım olmadığından, kurbağa gelecekte tekrar ne zaman dikkatimi çekeceğini biliyor. En iyi cevabı düzenlediğinizi görebiliyorum, bu yüzden bu yazıdaki malzememi ödünç almaktan / alıntı yapmaktan çekinmeyin (ve eğer apropos olursa bana alıntı yapın!)
Aaron Hall

23

Python üçlü operatörünün simülasyonu.

Örneğin

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

çıktı:

'b greater than a'

Neden basit değil result = (y, x)[a < b]Neden lambdaişlevi kullanıyorsunuz ?
Grijesh Chauhan

5
@GrijeshChauhan "Uyumlu" ifadelerde, örneğin bir işlev çağrısı vb. İçerdiğinden, bu her iki durumda da yürütülür. Bu istenmeyebilir.
glglgl

20

Üçlü koşullu işleç, bir koşulun tek satırda test edilmesine izin verir, aksi takdirde kodu kompakt hale getirirse çok satırlı yerine geçer.

Sözdizimi:

[on_true] eğer [ifade] başka ise [on_false]

1- Üçlü operatörü kullanmanın basit yöntemi:

# 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- Doğrudan tuples, sözlük ve lambda kullanma yöntemi:

# 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- Üçlü operatör iç içe olarak yazılabilir, aksi takdirde:

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

Yukarıdaki yaklaşım şu şekilde yazılabilir:

# 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
Üçlü operatörün daha küçük (bellekte) ve iç içe olandan daha hızlı olduğuna dikkat edin. Ayrıca, iç içe if-elsegeçmişiniz üçlü işlecin yeniden yazılması değildir ve a ve b'nin belirli değerleri için farklı çıktılar üretecektir (özellikle biri garip bir __ne__yöntemi uygulayan bir türse ).
Perkins

19

Bunu yapabilirsiniz :-

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

Misal:-

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

Bu, sayı tekse "tek" veya sayı çiftse "çift" olarak yazdırılır.


Sonuç: - Koşul doğruysa exp_1 yürütülürse exp_2 yürütülür.

Not: - 0, Yok, Yanlış, boş liste, emptyString Yanlış olarak değerlendirilir. Ve 0 dışında herhangi bir veri True olarak değerlendirilir.

Şöyle çalışır:

koşul [koşul] "Doğru" olursa, ifade_1 değerlendirilir, ancak ifade_2 olmaz. 0 (sıfır) ile bir şey "ve" yaparsak, sonuç her zaman tılsım olur.

0 and exp

Exp ifadesi hiç değerlendirilmeyecektir çünkü "ve" 0 ile her zaman sıfır olarak değerlendirilir ve ifadeyi değerlendirmeye gerek yoktur. Derleyicinin kendisi, tüm dillerde böyle çalışır.

İçinde

1 or exp

"veya" ifadesi 1 ile her zaman 1 olacağından exp ifadesi hiç değerlendirilmeyecektir. Dolayısıyla, sonuç yine de 1 olacağından exp ifadesini değerlendirmek zahmet etmeyecektir. derleyici optimizasyon yöntemleri.

Ancak

True and exp1 or exp2

İkinci ifade exp2 değerlendirilmeyecektir çünkü True and exp1exp1 yanlış olmadığında True olur.

Benzer şekilde

False and exp1 or exp2

Exp1 ifadesi False 0 yazmaya eşdeğer olduğu ve "ve" 0 ile 0'ın kendisi olacağı için değerlendirilmez, ancak exp1'den sonra "veya" kullanıldığından "veya" sonra exp2 ifadesini değerlendirir.


Not: - "veya" ve "ve" kullanarak bu tür dallanma, yalnızca expression_1 öğesi, True değerinin False değerine (veya 0 veya None veya emptylist [] veya emptystring ''.) Sahip olmadığında kullanılabilir. Yanlışsa, exp_1 ve exp_2 arasında "veya" varlığından dolayı expression_2 öğesi değerlendirilir.

Exp_1 ve exp_2 doğruluk değerlerinin ne olduğuna bakılmaksızın, tüm durumlar için hala çalışmasını istiyorsanız, bunu yapın: -

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


Eğer bağlamında bu kullanmak istiyorsanız x = [condition] and ([expression_1] or 1) or [expression_2]ve expression_1yanlış olarak değerlendirildiğini, xolacak 1, değil expression_1. Kabul edilen cevabı kullanın.
moi

18

Bir cevaptan daha fazla bir ipucu (hundreth için bariz olanı tekrarlamanız gerekmez), ancak bazen bu tür yapılarda bir oneliner kısayolu olarak kullanıyorum:

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

, olur:

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

Bazıları (birçok :) üzerinde unpythonic (hatta, ruby-ish :) olarak kaşlarını çattırabilirim, ama kişisel olarak daha doğal buluyorum - yani normal olarak nasıl ifade edeceğiniz, ayrıca büyük kod bloklarında biraz daha görsel olarak çekici.


5
print( 'yes' if conditionX else 'nah' )Cevabınızı tercih ederim . :-)
frederick99

Eğer print()her iki durumda da istiyorsanız - ve biraz daha pitonik görünüyor, itiraf etmeliyim :) Ama ya ifadeler / fonksiyonlar aynı değilse - gerçeğiprint('yes') if conditionX else Trueprint()conditionX
Todor Minakov

Frederick99'un print('yes') if conditionX else print('nah')sözüne eklemek için, kaçınmanın bir başka nedeni de Python2'de bir SyntaxError vermesidir.
Thierry Lathuille

Bir sözdizimi hatası vermesinin tek nedeni, Python 2'de bir deyimin - bir ifadesidir - print "yes"Python 3'te ise bir işlevdir - print("yes"). Bu, bir ifade olarak veya daha iyisi kullanılarak çözülebilir from future import print_function.
Todor Minakov

18
a if condition else b

Hatırlamakta güçlük çekiyorsanız, bu piramidi ezberleyin:

     condition
  if           else
a                   b 

14

Python'un koşullu ifadesinin alternatiflerinden biri

"yes" if boolean else "no"

takip ediliyor:

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

aşağıdaki güzel uzantıya sahiptir:

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

En kısa alternatif kalır:

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

ama başka alternatifi yok

yes() if boolean else no()

Eğer değerlendirmesini kaçınmak istiyorsanız yes() ve no() , çünkü

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

hem no()ve yes()değerlendirilir.


10

Türetilmiş birçok programlama dili Cgenellikle üçlü koşullu işleç sözdizimine sahiptir:

<condition> ? <expression1> : <expression2>

İlk başta, Python B enevolent D ictator F veya L ife (yani Guido van Rossum, elbette) bunu reddetti ( Pitonik olmayan bir tarz olarak), çünkü Cdil için alışkın olmayan insanlar için anlamak oldukça zor . Ayrıca, iki nokta üst üste işaretinin :zaten birçok kullanımı vardır Python. PEP 308 onaylandıktan sonra , Pythonsonunda kendi kısayol koşullu ifadesini aldı (şimdi kullandığımız şey):

<expression1> if <condition> else <expression2>

Yani, öncelikle durumu değerlendirir. O dönerse True, deyim1 aksi takdirde sonuç vermeye değerlendirilecektir ifade2 değerlendirilecektir. Tembel Değerlendirme mekaniği nedeniyle - sadece bir ifade yürütülür.

İşte bazı örnekler (koşullar soldan sağa değerlendirilecektir):

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

# Result is 'High'

Üçlü operatörler seri olarak zincirlenebilir:

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

# Result is 'Normal'

Aşağıdaki bir öncekiyle aynıdır:

pressure = 5

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

# Result is 'Normal'

Bu yardımcı olur umarım.


10

Daha önce yanıtlandığı gibi, evet python'da üçlü bir operatör var:

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

Ek bilgi:

Eğer <expression 1>durumdur kullanabileceğiniz Kısa cirquit değerlendirme :

a = True
b = False

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

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

Not: Elbette, Kısa devre değerlendirmesi üçlü bir operatör değildir, ancak kısa devrenin yeterli olacağı durumlarda genellikle üçlü kullanılır.


1
Bu short-circuitdeğerlendirme için oy verin.
CodeIt

7

EVET, python'un üçlü bir operatörü var, işte sözdizimi ve bunu göstermek için bir örnek kod :)

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

Hangi sayının daha ayrıntılı olarak ele alınacağını kontrol etmek için tek satırlık bir ifade örneği
ekledim

1
printgerçekten iyi bir seçim değil, çünkü bu Python2'de bir SyntaxError verecek.
Thierry Lathuille

@Thierry Lathuille Burada print () işlevini print deyimi kullanmadım, print işlevi Python 3 için, print deyimi Python 2 için ise
PythonLover

Soru zaten SO üzerinde soruldu, sadece Python 2 ile deneyin ve kendiniz göreceksiniz. 'print (' merhaba '), Python 2.7'de mükemmel şekilde geçerli bir sözdizimidir, ancak ayrıştırılma biçimi yukarıdaki kodunuzu bir SyntaxError atar.
Thierry Lathuille

2

Python'un ödevler için üçlü bir formu vardır; ancak insanların farkında olması gereken daha kısa bir form bile olabilir.

Bir koşula bağlı olarak bir değişkene bir değer veya başka bir değer atamanız çok yaygındır.

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

^ Bu, bu tür görevleri yapmak için uzun formdur.

Üçlü form aşağıdadır. Ancak bu en kısa yol değildir - son örneğe bakın.

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

Python ile oralternatif atamalar için kullanabilirsiniz .

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

Çünkü yukarıda eserler li1olduğunu Noneo mantık ifadelerde yanlış olarak ve interp davranır. İnterp daha sonra devam eder ve ikinci ifadeyi değerlendirir, ki bu değildir Noneve boş bir liste değildir - böylece a'ya atanır.

Bu, boş listelerle de çalışır. Örneğin, ahangi listede öğe varsa atamak istiyorsanız .

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

Bunu bilerek, bu tür ödevleri her karşılaştığınızda kolayca yapabilirsiniz. Bu, dizeler ve diğer yinelenebilir öğelerle de çalışır. aHangi dize boş değilse atayabilirsiniz .

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

Her zaman C üçlü sözdizimini sevdim, ama Python bunu bir adım daha ileri götürüyor!

Bazılarının bunun iyi bir stilistik seçim olmadığını söyleyebileceğini anlıyorum, çünkü tüm geliştiriciler tarafından hemen görülmeyen mekaniklere dayanıyor. Ben şahsen bu görüşe katılmıyorum. Python, dabler tarafından hemen görülmeyen birçok deyimsel hileye sahip sözdizimi açısından zengin bir dildir. Fakat altta yatan sistemin mekaniğini ne kadar çok öğrenir ve anlarsanız, o kadar çok takdir edersiniz.


1

Diğer cevaplar Python üçlü operatörü hakkında doğru konuşuyor. Üçlü operatörün sıkça kullanıldığı ancak daha iyi bir deyim olduğu bir senaryodan söz etmek istiyorum. Bu, varsayılan bir değer kullanma senaryosudur.

option_valueAyarlanmadıysa varsayılan bir değerle kullanmak istediğimizi varsayalım :

run_algorithm(option_value if option_value is not None else 10)

ya da sadece

run_algorithm(option_value if option_value else 10)

Ancak, daha iyi bir çözüm basitçe yazmaktır

run_algorithm(option_value or 10)

-2

değişken tanımlanmışsa ve değerinin olup olmadığını kontrol etmek istiyorsanız, 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)

çıktı olacak

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

1
Benzer problemler için yararlı olsa da, bu üçlü bir şart değildir. Değiştirmek için çalışıyor x if x else y, ama değil x if z else y.
Perkins

-2

Birden çok operatörü zincirlemenin düzgün bir yolu:

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

Ben varsayılan python sözdizimi hantal buluyorum val = a if cond else b, bu yüzden bazen bunu yapmak:

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

Tabii ki, her iki tarafı da (a ve b) değerlendirmenin dezavantajı var, ancak sözdizimi benim için çok daha net


Bu, iş miktarının iki katı, daha fazla RAM kullanımı ve daha basit val = a if cond else bifadeden daha gizlenmiş gibi görünüyor .
eatsfood

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

**

ihtiyaç olarak iç içe olabilir. iyi şanslar

**

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.