Bir satıra if-elif-else ifadesi mi koymak?


125

Aşağıdaki bağlantıları okudum, ancak soruma cevap vermiyor.
Python'un üçlü koşullu operatörü var mı? (soru, if-else ifadesini tek satırda yoğunlaştırmakla ilgilidir)

If-elif-else ifadesini tek satıra sığması için yazmanın daha kolay bir yolu var mı?
Örneğin,

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

Veya gerçek dünya örneği:

if i > 100:
    x = 2
elif i < 100:
    x = 1
else:
    x = 0

Sadece yukarıdaki örnek şu şekilde yazılabilirse, daha özlü görünebilir diye düşünüyorum.

x=2 if i>100 elif i<100 1 else 0 [WRONG]

Yanıtlar:


186

Hayır, mümkün değil (en azından keyfi ifadelerle) ve arzu edilen bir şey de değil. Her şeyi bir satıra sığdırmak , büyük olasılıkla satırların 80 karakteri geçmemesinin zorunlu olduğu durumlarda PEP-8'i ihlal eder.

Aynı zamanda Python Zen'e de aykırıdır: "Okunabilirlik önemlidir". (Her import thisşeyi okumak için Python istemine yazın).

Sen olabilir ama sadece ifadeleri değil, tablolar için, Python bir üçlü ifadesini kullanın:

>>> a = "Hello" if foo() else "Goodbye"

Düzenle:

Gözden geçirilmiş sorunuz artık üç ifadenin atanan değer dışında aynı olduğunu gösteriyor. Bu durumda, zincirli bir üçlü operatör çalışır, ancak yine de daha az okunabilir olduğunu düşünüyorum:

>>> i=100
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
0
>>> i=101
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
2
>>> i=99
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
1

İkinci ifade neden 0 döndürmedi? i 100'ün üzerindeyim
AstralWolf

6
@AstralWolf: Çok teşekkür ederim! Bu, yapmaya çalıştığım noktayı mükemmel bir şekilde gösteriyor - zincirlenmiş bir üçlü ifade mümkündür, ancak daha az okunabilir ve açıkça yanlış anlaşılması kolaydır.
Tim Pietzcker

1
Daha okunaklı olması gerekiyorsa, etrafına parantezler koyabilirsin, şöyle: a = 1 if i < 100 else (2 if i > 100 else 0)(Test edilmedi, ama işe yarayacağını düşünüyorum)
Zac

@TimPietzcker İfadeler ve ifadeler arasındaki farkı nasıl tanımlarsınız?
AsheKetchum

62

Yalnızca farklı durumlar için farklı ifadelere ihtiyacınız varsa, bu sizin için işe yarayabilir:

expr1 if condition1 else expr2 if condition2 else expr

Örneğin:

a = "neg" if b<0 else "pos" if b>0 else "zero"

1
"pos"olduğu değil , bu bir deyim ifadesidir.
Tim Pietzcker

@TimPietzcker Teşekkürler, gönderiyi daha doğru olacak şekilde güncelledim.
Lycha

20

Sadece else deyimine başka bir if cümlesi yerleştirin. Ama bu onu daha güzel göstermez.

>>> x=5
>>> x if x>0 else ("zero" if x==0 else "invalid value")
5
>>> x = 0
>>> x if x>0 else ("zero" if x==0 else "invalid value")
'zero'
>>> x = -1
>>> x if x>0 else ("zero" if x==0 else "invalid value")
'invalid value'

1
Benim için bu, kabul edilen cevaptan çok daha okunabilir çünkü birinci cümlenin yapısını ve konseptini koruyor; sadece öznel mesele.
Ezarate11

12

Diğer bazı cevaplara rağmen: EVET mümkün :

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

aşağıdaki tek satıra çevirir:

statement1 if expression1 else (statement2 if expression2 else statement3)

aslında bunları sonsuza kadar iç içe geçirebilirsiniz. Zevk almak ;)


geçen zaman nasıl? tahmin ettiğim gibi, bu çoklu döngü çok daha fazla zaman alacak. daha hızlı tüketim için iç içe döngülere bir alternatif olabilir.
aşkR

merhaba @loveR, bu döngü değil, sadece iç içe geçmiş bir ifade ve bu nedenle ihmal edilebilir bir süre
gustavz

7

Aslında isteğe bağlı getolarak a yöntemini kullanabilirsiniz dict:

x = {i<100: -1, -10<=i<=10: 0, i>100: 1}.get(True, 2)

getAnahtarlardan birinin aşağıdakileri değerlendirmesi garantiliyse yönteme ihtiyacınız yoktur True:

x = {i<0: -1, i==0: 0, i>0: 1}[True]

Anahtarlardan en fazla biri ideal olarak değerlendirilmelidir True. Birden fazla anahtar değerlendirilirse True, sonuçlar tahmin edilemez görünebilir.



4
if i > 100:
    x = 2
elif i < 100:
    x = 1
else:
    x = 0

Yukarıda belirtilen kodu tek satırda kullanmak isterseniz, aşağıdakileri kullanabilirsiniz:

x = 2 if i > 100 else 1 if i < 100 else 0

Bunu yaparken, x'e atanacak 2 eğer i> 100 ise, 1 ise i <100 ise 1 ve i = 100 ise 0


3

Aynı zamanda ifadelerinizin doğasına da bağlıdır. "Yapmama" şeklindeki diğer yanıtlar hakkındaki genel tavsiye, genel ifadeler ve genel ifadeler için oldukça geçerlidir.

Ancak, ihtiyacınız olan tek şey bir "gönderim" tablosu ise, örneğin belirli bir seçeneğin değerine bağlı olarak farklı bir işlevi çağırmaksa, işlevleri bir sözlüğün içine yerleştirebilirsiniz.

Gibi bir şey:

def save(): 
   ...
def edit():
   ...
options = {"save": save, "edit": edit, "remove": lambda : "Not Implemented"}

option = get_input()
result = options[option]()

If-else yerine:

if option=="save":
    save()
...

2

İnsanlar zaten üçlü ifadelerden bahsetmişlerdir. Bazen örneğiniz olarak basit bir koşullu atama ile koşullu atamayı gerçekleştirmek için matematiksel bir ifade kullanmak mümkündür. Bu, kodunuzu çok okunabilir yapmayabilir, ancak onu oldukça kısa bir satırda alır. Örneğiniz şu şekilde yazılabilir:

x = 2*(i>100) | 1*(i<100)

Karşılaştırmalar Doğru veya Yanlış olacaktır ve sayılarla çarpıldığında 1 veya 0 olacaktır. Bir | | yerine a + kullanılabilir. ortada.


1

Üçlü operatör özlü ifadesi için en iyi yoldur. Sözdizimi variable = value_1 if condition else value_2. Dolayısıyla, örneğiniz için üçlü operatörü iki kez uygulamanız gerekir:

i = 23 # set any value for i
x = 2 if i > 100 else 1 if i < 100 else 0

0

İç içe geçmiş if ifadeleri kullanabilirsiniz.

# if-else ternary construct
country_code = 'USA'
is_USA = True if country_code == 'USA' else False
print('is_USA:', is_USA)

# if-elif-else ternary construct
# Create function to avoid repeating code.
def get_age_category_name(age):
    age_category_name = 'Young' if age <= 40 else ('Middle Aged' if age > 40 and age <= 65 else 'Senior')
    return age_category_name

print(get_age_category_name(25))
print(get_age_category_name(50))
print(get_age_category_name(75))
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.