`elif` dalam kondisional pemahaman daftar

129

Bisakah kita menggunakan elifdalam pemahaman daftar?

Contoh:

l = [1, 2, 3, 4, 5]

for values in l:
    if values==1:
        print 'yes'
    elif values==2:
        print 'no'
    else:
        print 'idle'

Bisakah kita memasukkan elifdalam pemahaman daftar kita, dengan cara yang mirip dengan kode di atas?

Misalnya, jawaban seperti:

['yes', 'no', 'idle', 'idle', 'idle']

Sampai sekarang, saya hanya menggunakan ifdan elsedalam pemahaman daftar.

diri
sumber

Jawaban:

250

Ekspresi kondisional Python dirancang tepat untuk use-case semacam ini:

>>> l = [1, 2, 3, 4, 5]
>>> ['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]
['yes', 'no', 'idle', 'idle', 'idle']

Semoga ini membantu :-)

Raymond Hettinger
sumber
5
Ada beberapa sejarah menarik dalam sintaksisnya. Selama bertahun-tahun sebelum diperkenalkan, "ekspresi tersier" adalah salah satu dari lima perubahan yang paling banyak diminta dalam bahasa tersebut. Karena Guido van Rossum secara eksplisit mendesainnya sebagai bahasa berbasis pernyataan, dia dengan tegas menolak untuk waktu yang lama (ekspresi tersier, dan terutama pelecehannya, adalah sumber dari banyak ketidakjelasan dalam kode). Ketika dia akhirnya menyerah, dia mengumumkan bahwa dia sengaja memilih sintaks yang mencegah penggunaan berlebihan. Seperti biasa, dia melakukan pekerjaan desain yang elegan.
holdenweb
1
Ternary, sialan (dia menulis, menyadari kesalahan disleksia terlambat untuk diedit).
holdenweb
2
Sementara saya memilih jawaban ini, saya ingin menyebutkan ini: untuk 1 pasang if / else mudah dibaca, 2 pasang: semakin sulit untuk dipahami. Jangan sebutkan 3 pasang. Jika ekspresi membutuhkan 3 pasangan atau lebih, kamus atau fungsi terpisah akan membuat segalanya lebih mudah dibaca dan dipahami.
Hai Vu
1
Saya tidak ingin menambahkan solusi untuk masalah ini, tetapi pengingat kode yang bersih: karena pemahaman daftar ini memiliki tiga persyaratan, mungkin dapat direfraktorisasi menjadi metode yang lebih deskriptif. Maksud saya adalah ini: martinfowler.com/bliki/FunctionLength.html :)
Alvaro Cavalcanti
Saya menemukan kasus di mana saya membutuhkan elif, tetapi hanya dua nilai. Menggunakan contoh ini, saya hanya ['yes', 'no']perlu dibuat. Untuk melakukan ini, Anda dapat melakukan: ['yes' if v == 1 else 'no' for v in l if values in [1,2]]. Saat ini saya tidak dapat memikirkan cara yang lebih bersih untuk melakukan ini.
dTanMan
48
>>> d = {1: 'yes', 2: 'no'}
>>> [d.get(x, 'idle') for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
Ignacio Vazquez-Abrams
sumber
4
Saya pikir formulir ini jauh lebih mudah dicerna daripada mencoba membuat logika if / else yang sangat panjang dan rumit dalam daftar comp
jdi
5
@jdi Meskipun ekspresi-kondisional mungkin tidak sesuai dengan selera Anda, mereka secara khusus dirancang untuk menangani rantai if-elif-elif-else, seperti yang diminta OP. Mereka tidak sulit untuk belajar dan anggun dapat menangani situasi yang tidak setuju dengan logika lookup kamus: 'A' if grade>=90 else 'B' if grade>=80 else 'C' if grade>=70 else 'F'.
Raymond Hettinger
1
Jika ada keuntungan mendefinisikan di dluar pemahaman?
Chris_Rands
Alasan saya lebih menyukai pemahaman daftar adalah karena bacanya seperti bahasa Inggris. Bahkan seorang non-programmer akan dapat memahami apa yang dilakukannya. Dengan solusi ini Anda harus memahami metode dict.get ().
Tim Skov Jacobsen
26

Anda bisa, semacam itu.

Perhatikan bahwa ketika Anda menggunakan sytax seperti:

['yes' if v == 1 else 'no' for v in l]

Anda menggunakan bentuk terner dari operator if / else (jika Anda terbiasa dengan bahasa seperti C, ini seperti ?:konstruksinya :) (v == 1 ? 'yes' : 'no').

Bentuk terner dari operator if / else tidak memiliki 'elif' bawaan, tetapi Anda dapat mensimulasikannya dalam kondisi 'else':

['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]

Ini seperti mengatakan:

for v in l:
    if v == 1 :
        print 'yes'
    else:
        if v == 2:
            print 'no'
        else:
            print 'idle'

Jadi tidak ada konstruksi 'elif' langsung seperti yang Anda tanyakan, tetapi dapat disimulasikan dengan pernyataan if / else bersarang.

mathematical.coffee
sumber
1
Kode paragraf terakhir adalah terima kasih yang sangat berwawasan!
devianceee
3

Mungkin Anda menginginkan ini:

l = [1, 2, 3, 4, 5] 

print ([['idle','no','yes'][2*(n==1)+(n==2)] for n in l])
Ratnesh Kushwaha
sumber
2

Anda dapat menggunakan pemahaman daftar jika Anda akan membuat daftar lain dari aslinya.

>>> l = [1, 2, 3, 4, 5]
>>> result_map = {1: 'yes', 2: 'no'}
>>> [result_map[x] if x in result_map else 'idle' for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
San4ez
sumber
2

Cara mudah lainnya adalah dengan menggunakan pemahaman daftar bersyarat seperti ini:

l=[1,2,3,4,5]
print [[["no","yes"][v==1],"idle"][v!=1 and v!=2] for v in l]

memberi Anda jawaban yang benar:

['yes', 'no', 'idle', 'idle', 'idle']

Stefan Gruenwald
sumber