Jika Python tidak memiliki operator kondisional ternary, apakah mungkin untuk mensimulasikan satu menggunakan konstruksi bahasa lain?
python
operators
ternary-operator
conditional-operator
Dikhususkan
sumber
sumber
case [...] { when ... then ...} [ else ... ] end
efek yang serupa tetapi sama sekali tidak ternary.Jawaban:
Ya, itu ditambahkan dalam versi 2.5. Sintaks ekspresi adalah:
Pertama
condition
dievaluasi, maka tepat satu dari baika
ataub
dievaluasi dan dikembalikan berdasarkan Boolean nilaicondition
. Jikacondition
dievaluasiTrue
, makaa
dievaluasi dan dikembalikan tetapib
diabaikan, atau kalaub
tidak dievaluasi dan dikembalikan tetapia
diabaikan.Ini memungkinkan hubungan arus pendek karena ketika
condition
benar hanyaa
dievaluasi danb
tidak dievaluasi sama sekali, tetapi ketikacondition
salah hanyab
dievaluasi dana
tidak dievaluasi sama sekali.Sebagai contoh:
Perhatikan bahwa conditional adalah ekspresi , bukan pernyataan . Ini berarti Anda tidak dapat menggunakan pernyataan penugasan
pass
atau pernyataan lain dalam ekspresi bersyarat :Anda bisa, bagaimanapun, menggunakan ekspresi kondisional untuk menetapkan variabel seperti:
Pikirkan ungkapan kondisional sebagai peralihan di antara dua nilai. Ini sangat berguna ketika Anda berada dalam situasi 'satu nilai atau yang lain', itu tetapi tidak melakukan banyak hal lain.
Jika Anda perlu menggunakan pernyataan, Anda harus menggunakan
if
pernyataan normal alih-alih ekspresi kondisional .Perlu diingat bahwa itu disukai oleh beberapa Pythonista karena beberapa alasan:
condition ? a : b
operator ternary klasik dari banyak bahasa lain (seperti C, C ++, Go, Perl, Ruby, Java, Javascript, dll.), Yang dapat menyebabkan bug ketika orang tidak terbiasa dengan Python " "perilaku mengejutkan menggunakannya (mereka dapat membalik urutan argumen).if
' dapat sangat berguna, dan membuat skrip Anda lebih ringkas, itu benar-benar menyulitkan kode Anda)Jika Anda kesulitan mengingat urutannya, maka ingatlah bahwa ketika membaca dengan keras, Anda (hampir) mengatakan apa yang Anda maksudkan. Misalnya,
x = 4 if b > 8 else 9
dibacakan dengan keras sebagaix will be 4 if b is greater than 8 otherwise 9
.Dokumentasi resmi:
sumber
f(x) = |x| = x if x > 0 else -x
terdengar sangat alami untuk ahli matematika. Anda mungkin juga memahaminya seperti halnya A dalam kebanyakan kasus, kecuali ketika C maka Anda harus melakukan B sebagai gantinya ...z = 3 + x if x < y else y
. Jikax=2
dany=1
, Anda mungkin berharap untuk menghasilkan 4, tetapi sebenarnya akan menghasilkan 1.z = 3 + (x if x > y else y)
adalah penggunaan yang benar.z = 3 + x if x < y else 3 + y
), atau grup kondisional (z = 3 + (x if x < y else y)
atauz = (x if x < y else y) + 3
)Anda dapat mengindeks menjadi tuple:
test
perlu mengembalikan Benar atau Salah .Mungkin lebih aman untuk selalu menerapkannya sebagai:
atau Anda dapat menggunakan bawaan
bool()
untuk memastikan nilai Boolean :sumber
(lambda: print("a"), lambda: print("b"))[test==true]()
[]
s dapat berupa ekspresi yang sewenang-wenang. Juga, untuk keamanan Anda dapat secara eksplisit menguji kebenaran dengan menulis[bool(<expression>)]
. Thebool()
Fungsi telah ada sejak v2.2.1.True
danFalse
sebagai kuncinya:{True:trueValue, False:falseValue}[test]
Saya tidak tahu apakah ini kurang efisien, tetapi setidaknya menghindari keseluruhan Debat "elegan" vs. "jelek". Tidak ada ambiguitas yang Anda hadapi dengan boolean daripada int.Untuk versi sebelum 2.5, ada triknya:
Ini dapat memberikan hasil yang salah ketika
on_true
memiliki nilai boolean palsu. 1Meskipun memiliki manfaat mengevaluasi ekspresi dari kiri ke kanan, yang lebih jelas menurut saya.
1. Apakah ada yang setara dengan C's "?:" Operator ternary?
sumber
<expression 1> if <condition> else <expression 2>
sumber
Dari dokumentasi :
Baru sejak versi 2.5.
sumber
Operator untuk ekspresi kondisional dalam Python ditambahkan pada 2006 sebagai bagian dari Proposal Peningkatan Python 308 . Bentuknya berbeda dari
?:
operator umum dan itu:yang setara dengan:
Berikut ini sebuah contoh:
Sintaks lain yang dapat digunakan (kompatibel dengan versi sebelum 2.5):
di mana operan dievaluasi dengan malas .
Cara lain adalah dengan mengindeks tupel (yang tidak konsisten dengan operator bersyarat dari sebagian besar bahasa lain):
atau kamus yang dibangun secara eksplisit:
Metode lain (kurang dapat diandalkan), tetapi lebih sederhana adalah menggunakan
and
danor
operator:Namun ini tidak akan berhasil jika
x
mauFalse
.Solusi yang mungkin adalah membuat
x
dany
mendaftar atau tupel sebagai berikut:atau:
Jika Anda bekerja dengan kamus, alih-alih menggunakan kondisional terner, Anda dapat memanfaatkan
get(key, default)
, misalnya:Sumber: ?: Dalam Python di Wikipedia
sumber
result = {1: x, 0: y}[a > b]
adalah varian lain yang mungkin (True
danFalse
sebenarnya bilangan bulat dengan nilai-nilai1
dan0
)Sayangnya
solusi tidak memiliki perilaku hubung singkat; dengan demikian keduanya
falseValue
dantrueValue
dievaluasi terlepas dari kondisinya. Ini bisa suboptimal atau bahkan buggy (yaitu keduanyatrueValue
danfalseValue
bisa menjadi metode dan memiliki efek samping).Salah satu solusi untuk ini adalah
(eksekusi tertunda hingga pemenang diketahui;)), tetapi memperkenalkan inkonsistensi antara objek yang dapat dipanggil dan tidak dapat dipanggil. Selain itu, itu tidak menyelesaikan kasus saat menggunakan properti.
Dan begitulah ceritanya - memilih antara 3 solusi yang disebutkan adalah trade-off antara memiliki fitur hubung singkat, menggunakan setidaknya Зython 2.5 (IMHO bukan masalah lagi) dan tidak rentan terhadap
trueValue
kesalahan " -evaluates-to-false" .sumber
if else if
.Operator ternary dalam Bahasa pemrograman yang berbeda
Di sini saya hanya mencoba untuk menunjukkan beberapa perbedaan penting di
ternary operator
antara beberapa bahasa pemrograman.sumber
Untuk Python 2.5 dan yang lebih baru ada sintaksis spesifik:
Pada Python lama, operator ternary tidak diimplementasikan tetapi dimungkinkan untuk mensimulasikannya.
Padahal, ada masalah potensial, yang jika
cond
dievaluasiTrue
danon_true
dievaluasiFalse
kemudianon_false
dikembalikanon_true
. Jika Anda ingin perilaku ini metode ini OK, jika tidak gunakan ini:yang bisa dibungkus dengan:
dan digunakan dengan cara ini:
Ini kompatibel dengan semua versi Python.
sumber
q("blob", on_true, on_false)
pengembalianon_false
, sedangkanon_true if cond else on_false
pengembalianon_true
. Sebuah solusi adalah untuk menggantikancond
dengancond is not None
dalam kasus ini, meskipun itu bukan solusi sempurna.bool(cond)
bukancond is True
? Yang pertama memeriksa kebenarancond
, yang terakhir memeriksa pointer-kesetaraan denganTrue
objek. Seperti yang disorot oleh @AndrewCecil,"blob"
itu benar tapi ituis not True
.[on_false, on_True][cond is True]
sehingga ekspresi menjadi lebih pendek.Anda mungkin sering menemukan
tapi ini menyebabkan masalah ketika on_true == 0
di mana Anda harapkan untuk operator ternary normal hasil ini
sumber
Iya. Dari file tata bahasa :
Bagian yang menarik adalah:
Jadi, operasi kondisional ternary adalah dalam bentuk:
expression3
akan dievaluasi dengan malas (yaitu, dievaluasi hanya jikaexpression2
salah dalam konteks boolean). Dan karena definisi rekursif, Anda dapat rantai mereka tanpa batas (meskipun mungkin dianggap gaya yang buruk.)Catatan tentang penggunaan:
Perhatikan bahwa setiap
if
harus diikuti denganelse
. Orang-orang yang mempelajari daftar dan ekspresi generator mungkin menemukan ini menjadi pelajaran yang sulit untuk dipelajari - yang berikut tidak akan berhasil, karena Python mengharapkan ekspresi ketiga untuk yang lain:yang menimbulkan a
SyntaxError: invalid syntax
. Jadi di atas adalah salah satu bagian logika yang tidak lengkap (mungkin pengguna mengharapkan no-op dalam kondisi salah) atau apa yang mungkin dimaksudkan adalah menggunakan ekspresi2 sebagai filter - perhatikan bahwa berikut ini adalah Python legal:expression2
berfungsi sebagai filter untuk pemahaman daftar, dan bukan operator kondisional ternary.Sintaks alternatif untuk kasus yang lebih sempit:
Anda mungkin merasa agak sakit menulis yang berikut ini:
expression1
harus dievaluasi dua kali dengan penggunaan di atas. Ini dapat membatasi redundansi jika hanya variabel lokal. Namun, idiom Pythonic yang umum dan performan untuk use-case ini adalah menggunakanor
perilaku pintas:yang setara dalam semantik. Perhatikan bahwa beberapa panduan gaya dapat membatasi penggunaan ini dengan alasan kejelasan - itu memang mengemas banyak makna menjadi sintaks yang sangat sedikit.
sumber
expression1 or expression2
menjadi serupa dan dengan kelemahan / positif yang sama sepertiexpression1 || expression2
di javascriptexpressionN
untuk semua instance konsisten, mungkin lebih mudah untuk memahami dengan penamaan yang membedakan ekspresi uji kondisional dari dua ekspresi hasil; misalnyaresult1 if condition else result2
,. Hal ini terutama jelas ketika bersarang (alias chaining):result1 if condition1 else result2 if condition2 else result3
. Lihat seberapa jauh lebih baik yang membaca dengan cara ini?Mensimulasikan operator terner python.
Sebagai contoh
keluaran:
sumber
result = (y, x)[a < b]
Mengapa Anda menggunakanlambda
fungsi ?Operator kondisional ternary hanya memungkinkan pengujian suatu kondisi dalam satu baris menggantikan multiline jika-jika membuat kode kompak.
Sintaks:
1- Metode Sederhana untuk menggunakan operator ternary:
2- Metode Langsung menggunakan tupel, Kamus, dan lambda:
3- Operator ternary dapat ditulis sebagai bersarang jika-ada:
Pendekatan di atas dapat ditulis sebagai:
sumber
if-else
sebenarnya bukan penulisan ulang dari operator ternary, dan akan menghasilkan output yang berbeda untuk nilai pilih a dan b (khususnya jika salah satu adalah tipe yang mengimplementasikan__ne__
metode aneh ).kamu bisa melakukan ini :-
[condition] and [expression_1] or [expression_2] ;
Contoh:-
print(number%2 and "odd" or "even")
Ini akan mencetak "ganjil" jika nomornya ganjil atau "genap" jika nomornya genap.
Hasilnya: - Jika kondisinya benar exp_1 dieksekusi lain exp_2 dieksekusi.
Catatan: - 0, Tidak Ada, Salah, daftar kosong, blankString dievaluasi sebagai False. Dan setiap data selain 0 bernilai True.
Begini cara kerjanya:
jika kondisi [kondisi] menjadi "Benar" maka, ekspresi_1 akan dievaluasi tetapi bukan ekspresi_2. Jika kita "dan" sesuatu dengan 0 (nol), hasilnya akan selalu fasle. Jadi dalam pernyataan di bawah ini,
Ekspresi ekspresi tidak akan dievaluasi sama sekali karena "dan" dengan 0 akan selalu bernilai nol dan tidak perlu mengevaluasi ekspresi. Ini adalah cara kerja kompiler itu sendiri, dalam semua bahasa.
Di
ekspresi exp tidak akan dievaluasi sama sekali karena "atau" dengan 1 akan selalu 1. Jadi, tidak akan repot untuk mengevaluasi ekspresi exp karena hasilnya tetap 1. (metode optimisasi kompiler).
Tetapi dalam kasus
Ekspresi kedua exp2 tidak akan dievaluasi karena
True and exp1
akan Benar ketika exp1 tidak salah.Demikian pula dalam
Ekspresi exp1 tidak akan dievaluasi karena False sama dengan menulis 0 dan melakukan "dan" dengan 0 akan menjadi 0 itu sendiri tetapi setelah exp1 sejak "atau" digunakan, ia akan mengevaluasi ekspresi exp2 setelah "atau".
Catatan: - Jenis percabangan ini menggunakan "atau" dan "dan" hanya dapat digunakan ketika ekspresi_1 tidak memiliki nilai Kebenaran Salah (atau 0 atau Tidak Ada atau daftar kosong [] atau emptystring ''.) Karena jika ekspresi_1 menjadi Salah, maka ekspresi_2 akan dievaluasi karena kehadiran "atau" antara exp_1 dan exp_2.
Jika Anda masih ingin membuatnya bekerja untuk semua kasus terlepas dari apa nilai kebenaran exp_1 dan exp_2, lakukan ini: -
[condition] and ([expression_1] or 1) or [expression_2] ;
sumber
x = [condition] and ([expression_1] or 1) or [expression_2]
danexpression_1
mengevaluasi ke false,x
akan1
, tidakexpression_1
. Gunakan jawaban yang diterima.Lebih banyak tip daripada jawaban (tidak perlu mengulang yang sudah jelas untuk waktu hundreth), tapi saya kadang menggunakannya sebagai pintasan oneliner dalam konstruksi seperti ini:
, menjadi:
Beberapa (banyak :) mungkin menganggapnya sebagai unpythonic (bahkan, ruby-ish :), tapi saya pribadi merasa lebih alami - yaitu bagaimana Anda akan mengekspresikannya secara normal, ditambah sedikit lebih menarik secara visual dalam blok kode besar.
sumber
print( 'yes' if conditionX else 'nah' )
daripada jawaban Anda. :-)print()
dalam kedua kasus - dan itu terlihat sedikit lebih pythonic, saya harus mengakui :) Tapi bagaimana jika ekspresi / fungsi tidak sama - sepertiprint('yes') if conditionX else True
- untuk mendapatkanprint()
satu - satunya yang benarconditionX
print('yes') if conditionX else print('nah')
adalah memberikan Sintaksis dalam Python2.print "yes"
, sedangkan dalam Python 3 itu adalah fungsi -print("yes")
. Itu dapat diatasi dengan menggunakannya sebagai pernyataan, atau lebih baik -from future import print_function
.Hafalkan piramida ini jika Anda kesulitan mengingat:
sumber
Salah satu alternatif untuk ekspresi kondisional Python
adalah sebagai berikut:
yang memiliki ekstensi yang bagus berikut:
Alternatif terpendek tetap:
tetapi tidak ada alternatif untuk
jika Anda ingin menghindari evaluasi
yes()
danno()
, karena dalamkeduanya
no()
danyes()
dievaluasi.sumber
Banyak bahasa pemrograman yang berasal dari
C
biasanya memiliki sintaksis dari operator kondisional ternary berikut:Jadi, pertama mengevaluasi kondisinya. Jika kembali
True
, ekspresi1 akan dievaluasi untuk memberikan hasilnya, jika tidak ekspresi2 akan dievaluasi. Karena mekanisme Evaluasi Malas - hanya satu ekspresi yang akan dieksekusi.Berikut adalah beberapa contoh (kondisi akan dievaluasi dari kiri ke kanan):
Operator ternary dapat dirantai secara seri:
Yang berikut ini sama dengan yang sebelumnya:
Semoga ini membantu.
sumber
Seperti yang sudah dijawab, ya ada operator ternary dengan python:
Informasi tambahan:
Jika
<expression 1>
kondisinya Anda dapat menggunakan evaluasi Short-cirquit :PS: Tentu saja, evaluasi Short-cirquit bukan operator ternary tetapi sering ternary digunakan dalam kasus-kasus di mana korsleting cukup.
sumber
short-circuit
evaluasi itu.YA, python memiliki operator ternary, ini adalah sintaks dan kode contoh untuk menunjukkan yang sama :)
sumber
print
benar-benar bukan pilihan yang baik, karena ini akan memberikan SyntaxError di Python2.Python memiliki bentuk terner untuk penugasan; namun mungkin ada bentuk yang lebih pendek yang harus disadari orang.
Sangat umum untuk perlu menetapkan variabel satu nilai atau yang lain tergantung pada suatu kondisi.
^ Ini adalah formulir panjang untuk melakukan penugasan tersebut.
Di bawah ini adalah bentuk terner. Tapi ini bukan cara yang paling ringkas - lihat contoh terakhir.
Dengan Python, Anda cukup menggunakan
or
untuk tugas alternatif.Karya-karya di atas, karena
li1
merupakanNone
dan memperlakukan interp bahwa sebagai False dalam ekspresi logika. Interp kemudian bergerak dan mengevaluasi ekspresi kedua, yang bukanNone
dan itu bukan daftar kosong - sehingga ditugaskan untuk.Ini juga berfungsi dengan daftar kosong. Misalnya, jika Anda ingin menetapkan
a
daftar mana saja yang memiliki item.Mengetahui hal ini, Anda dapat dengan mudah memberikan tugas seperti itu setiap kali Anda melihatnya. Ini juga berfungsi dengan string dan iterables lainnya. Anda dapat menetapkan
a
string mana pun yang tidak kosong.Saya selalu menyukai sintaks C ternary, tetapi Python mengambilnya selangkah lebih maju!
Saya mengerti bahwa beberapa orang mungkin mengatakan ini bukan pilihan gaya yang baik karena bergantung pada mekanik yang tidak segera terlihat oleh semua pengembang. Saya pribadi tidak setuju dengan sudut pandang itu. Python adalah bahasa yang kaya akan sintaksis dengan banyak trik idiomatis yang tidak segera terlihat oleh si penabrak. Tetapi semakin Anda belajar dan memahami mekanisme sistem yang mendasarinya, semakin Anda menghargainya.
sumber
Jawaban lain dengan benar berbicara tentang operator ternary Python. Saya ingin melengkapi dengan menyebutkan skenario yang sering digunakan operator ternary tetapi yang ada idiom yang lebih baik. Ini adalah skenario menggunakan nilai default.
Misalkan kita ingin menggunakan
option_value
dengan nilai default jika tidak disetel:atau sederhana
Namun, solusi yang lebih baik adalah menulis
sumber
jika variabel didefinisikan dan Anda ingin memeriksa apakah memiliki nilai Anda bisa saja
a or b
akan menampilkan
sumber
x if x else y
, tetapi tidakx if z else y
.Cara yang rapi untuk menghubungkan beberapa operator:
sumber
Saya menemukan rumit sintaks python default
val = a if cond else b
, jadi kadang-kadang saya melakukan ini:Tentu saja, ini memiliki kelemahan dari selalu mengevaluasi kedua belah pihak (a dan b), tetapi sintaksnya jauh lebih jelas bagi saya
sumber
val = a if cond else b
pernyataan yang lebih sederhana .**
**
sumber