Menempatkan pernyataan if-elif-else di satu baris?

124

Saya telah membaca tautan di bawah ini, tetapi itu tidak menjawab pertanyaan saya.
Apakah Python memiliki operator bersyarat terner? (pertanyaannya adalah tentang memadatkan pernyataan if-else menjadi satu baris)

Apakah ada cara yang lebih mudah untuk menulis pernyataan if-elif-else agar sesuai dalam satu baris?
Sebagai contoh,

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

Atau contoh dunia nyata:

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

Saya hanya merasa jika contoh di atas bisa ditulis dengan cara berikut, bisa jadi terlihat lebih ringkas.

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

Jawaban:

184

Tidak, itu tidak mungkin (setidaknya tidak dengan pernyataan sewenang-wenang), juga tidak diinginkan. Memasukkan semuanya dalam satu baris kemungkinan besar akan melanggar PEP-8 di mana ada mandat bahwa panjang baris tidak boleh melebihi 80 karakter.

Ini juga bertentangan dengan Zen of Python: "Jumlah keterbacaan". (Ketik import thispada prompt Python untuk membaca semuanya).

Anda dapat menggunakan ekspresi terner dengan Python, tetapi hanya untuk ekspresi, bukan untuk pernyataan:

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

Edit:

Pertanyaan Anda yang telah direvisi sekarang menunjukkan bahwa ketiga pernyataan itu identik kecuali untuk nilai yang diberikan. Dalam hal ini, operator terner yang dirantai berfungsi, tetapi menurut saya itu kurang terbaca:

>>> 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
Tim Pietzcker
sumber
Mengapa ekspresi kedua tidak mengembalikan 0? saya di atas 100
AstralWolf
6
@AstralWolf: Terima kasih banyak! Ini dengan sempurna mengilustrasikan poin yang saya coba buat - ekspresi terner yang dirantai mungkin tetapi kurang dapat dibaca, dan jelas mudah untuk disalahpahami.
Tim Pietzcker
1
Jika Anda membutuhkannya agar lebih mudah dibaca, Anda dapat meletakkan tanda kurung di sekitarnya, seperti ini: a = 1 if i < 100 else (2 if i > 100 else 0)(Belum diuji, tapi saya pikir itu harus berfungsi)
Zac
@TimPietzcker bagaimana Anda menjelaskan perbedaan antara ekspresi dan pernyataan?
AsheKetchum
62

Jika Anda hanya membutuhkan ekspresi yang berbeda untuk kasus yang berbeda maka ini mungkin berhasil untuk Anda:

expr1 if condition1 else expr2 if condition2 else expr

Sebagai contoh:

a = "neg" if b<0 else "pos" if b>0 else "zero"
Lycha
sumber
1
"pos"adalah tidak sebuah pernyataan, itu ekspresi.
Tim Pietzcker
@TimPietzcker Terima kasih, saya memperbarui pos agar lebih akurat.
Lycha
20

Hanya menumpuk klausa if lain di pernyataan lain. Tapi itu tidak membuatnya terlihat lebih cantik.

>>> 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'
David Lai
sumber
1
Bagi saya, ini jauh lebih mudah dibaca daripada jawaban yang diterima karena mempertahankan struktur dan konsep klausa pertama; hanya masalah subjektif.
Ezarate11
12

Terlepas dari beberapa jawaban lain: YA itu mungkin :

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

diterjemahkan menjadi satu baris berikut:

statement1 if expression1 else (statement2 if expression2 else statement3)

sebenarnya Anda bisa menyarangkannya sampai tak terbatas. Nikmati ;)

gustavz.dll
sumber
bagaimana dengan waktu yang dibutuhkan? menurut saya, muti-looping ini akan lebih memakan waktu. jadi bisa ada alternatif untuk loop bersarang, untuk kecepatan konsumsi yang lebih baik.
loveR
hai @loveR, ini bukan loop, ini hanya pernyataan bersarang jika lain, dan karenanya waktu yang dapat diabaikan
gustavz
7

Secara opsional, Anda dapat benar-benar menggunakan getmetode a dict:

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

Anda tidak memerlukan getmetode ini jika salah satu kunci dijamin akan dievaluasi ke True:

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

Paling-paling salah satu kunci idealnya harus dievaluasi ke True. Jika lebih dari satu kunci dievaluasi True, hasilnya mungkin tampak tidak dapat diprediksi.

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

Jika Anda ingin menggunakan kode yang disebutkan di atas dalam satu baris, Anda dapat menggunakan yang berikut ini:

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

Saat melakukannya, x akan diberikan 2 jika i> 100, 1 jika i <100 dan 0 jika i = 100

roshanpoudel.dll
sumber
3

Itu juga tergantung pada sifat ekspresi Anda. Saran umum tentang jawaban lain dari "tidak melakukannya" cukup valid untuk pernyataan umum dan ekspresi umum.

Tetapi jika yang Anda butuhkan hanyalah tabel "pengiriman", seperti, memanggil fungsi yang berbeda bergantung pada nilai opsi yang diberikan, Anda dapat meletakkan fungsi yang akan dipanggil di dalam kamus.

Sesuatu seperti:

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

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

Alih-alih jika-lain:

if option=="save":
    save()
...
jsbueno
sumber
2

Orang telah menyebutkan ekspresi terner. Terkadang dengan tugas bersyarat sederhana sebagai contoh Anda, dimungkinkan untuk menggunakan ekspresi matematika untuk melakukan tugas bersyarat. Ini mungkin tidak membuat kode Anda sangat mudah dibaca, tetapi membuatnya hanya dalam satu baris yang cukup pendek. Contoh Anda bisa ditulis seperti ini:

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

Perbandingannya adalah True atau False, dan saat mengalikan dengan angka akan menjadi 1 atau 0. Seseorang dapat menggunakan + sebagai ganti | di tengah-tengah.

Ant6n
sumber
1

The operator ternary adalah cara terbaik untuk ekspresi ringkas. Sintaksnya adalah variable = value_1 if condition else value_2. Jadi, misalnya, Anda harus menerapkan operator terner dua kali:

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

Anda bisa menggunakan terner if bersarang pernyataan.

# 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))
k0L1081
sumber