Apakah Python memiliki operator kondisional ternary?

6047

Jika Python tidak memiliki operator kondisional ternary, apakah mungkin untuk mensimulasikan satu menggunakan konstruksi bahasa lain?

Dikhususkan
sumber
149
Dalam dokumentasi resmi Python 3.0 yang dirujuk dalam komentar di atas, ini disebut sebagai "conditional_expressions" dan sangat didefinisikan secara samar. Dokumentasi itu bahkan tidak termasuk istilah "ternary", jadi Anda akan kesulitan menemukannya melalui Google kecuali Anda tahu persis apa yang harus dicari. The versi 2 dokumentasi agak lebih bermanfaat dan termasuk link ke "PEP 308" , yang mencakup banyak konteks sejarah yang menarik terkait dengan pertanyaan ini.
Nobar
26
"ternary" (memiliki tiga input) adalah properti konsekuensial dari penerapan ini, bukan properti yang menentukan konsep. misal: SQL memiliki case [...] { when ... then ...} [ else ... ] endefek yang serupa tetapi sama sekali tidak ternary.
user313114
10
juga ISO / IEC 9899 (standar bahasa pemrograman C) bagian 6.5.15 menyebutnya "operator kondisional"
user313114
9
Wikipedia membahas hal ini secara menyeluruh dalam artikel " ?: ".
HelloGoodbye
9
Pada tahun-tahun sejak komentar nobar, dokumentasi ekspresi kondisional telah diperbarui untuk mengatakan ekspresi Bersyarat (kadang-kadang disebut "operator ternary") ...
Scott Martin

Jawaban:

7045

Ya, itu ditambahkan dalam versi 2.5. Sintaks ekspresi adalah:

a if condition else b

Pertama conditiondievaluasi, maka tepat satu dari baik aatau bdievaluasi dan dikembalikan berdasarkan Boolean nilai condition. Jika conditiondievaluasi True, maka adievaluasi dan dikembalikan tetapi bdiabaikan, atau kalau btidak dievaluasi dan dikembalikan tetapi adiabaikan.

Ini memungkinkan hubungan arus pendek karena ketika conditionbenar hanya adievaluasi dan btidak dievaluasi sama sekali, tetapi ketika conditionsalah hanya bdievaluasi dan atidak dievaluasi sama sekali.

Sebagai contoh:

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

Perhatikan bahwa conditional adalah ekspresi , bukan pernyataan . Ini berarti Anda tidak dapat menggunakan pernyataan penugasan passatau pernyataan lain dalam ekspresi bersyarat :

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

Anda bisa, bagaimanapun, menggunakan ekspresi kondisional untuk menetapkan variabel seperti:

x = a if True else b

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:

  • Urutan argumen berbeda dari orang-orang dari condition ? a : boperator 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).
  • Beberapa orang merasa "berat", karena bertentangan dengan aliran pemikiran normal (memikirkan kondisi terlebih dahulu dan kemudian efeknya).
  • Alasan gaya. (Meskipun 'inline 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 9dibacakan dengan keras sebagai x will be 4 if b is greater than 8 otherwise 9.

Dokumentasi resmi:

Vinko Vrsalovic
sumber
269
Urutan mungkin tampak aneh untuk coders namun f(x) = |x| = x if x > 0 else -xterdengar 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 ...
yota
121
Hati-hati dengan urutan operasi saat menggunakan ini. Misalnya, garis z = 3 + x if x < y else y. Jika x=2dan y=1, Anda mungkin berharap untuk menghasilkan 4, tetapi sebenarnya akan menghasilkan 1. z = 3 + (x if x > y else y)adalah penggunaan yang benar.
Kal Zekdor
11
Intinya adalah jika Anda ingin melakukan evaluasi tambahan setelah kondisional dievaluasi, seperti menambahkan nilai pada hasilnya, Anda harus menambahkan ekspresi tambahan ke kedua sisi ( z = 3 + x if x < y else 3 + y), atau grup kondisional ( z = 3 + (x if x < y else y)atau z = (x if x < y else y) + 3)
Kal Zekdor
4
@ MrGeek, saya mengerti maksud Anda, jadi pada dasarnya Anda akan bersarang operasi: `" foo "jika Bool else (" bar "jika Bool else" foobar ")`
Dimesio
3
Pemrogram membutuhkan formulasi yang tepat bahkan lebih dari ahli matematika, karena dalam matematika selalu ada jalan untuk konsep yang mendasarinya. Argumen yang meyakinkan adalah operator%, meniru cara "mod" digunakan dalam matematika akan menjadi bencana. Jadi tidak, saya tidak menerima argumen Anda. Ini seperti mematuhi unit kekaisaran. Groetjes Albert
Albert van der Horst
799

Anda dapat mengindeks menjadi tuple:

(falseValue, trueValue)[test]

testperlu mengembalikan Benar atau Salah .
Mungkin lebih aman untuk selalu menerapkannya sebagai:

(falseValue, trueValue)[test == True]

atau Anda dapat menggunakan bawaan bool()untuk memastikan nilai Boolean :

(falseValue, trueValue)[bool(<expression>)]
Landon Kuhn
sumber
591
Perhatikan bahwa yang satu ini selalu mengevaluasi segalanya, sedangkan konstruksi if / else hanya mengevaluasi ekspresi kemenangan.
SilverbackNet
117
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz
15
Perlu dicatat bahwa apa yang ada di dalam []s dapat berupa ekspresi yang sewenang-wenang. Juga, untuk keamanan Anda dapat secara eksplisit menguji kebenaran dengan menulis [bool(<expression>)]. The bool()Fungsi telah ada sejak v2.2.1.
martineau
12
Saya telah melakukan trik serupa - hanya sekali atau dua kali, tetapi berhasil - dengan mengindeks ke dalam kamus dengan Truedan Falsesebagai 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.
JDM
338

Untuk versi sebelum 2.5, ada triknya:

[expression] and [on_true] or [on_false]

Ini dapat memberikan hasil yang salah ketika on_true memiliki nilai boolean palsu. 1
Meskipun memiliki manfaat mengevaluasi ekspresi dari kiri ke kanan, yang lebih jelas menurut saya.

1. Apakah ada yang setara dengan C's "?:" Operator ternary?

James Brady
sumber
67
Obatnya adalah dengan menggunakan (test dan [true_value] atau [false_value]) [0], yang menghindari jebakan ini.
ThomasH
6
Operator ternary biasanya menjalankan lebih cepat (kadang-kadang 10-25%).
gunung berapi
7
@volcano Apakah Anda punya sumber untuk saya?
OrangeTux
4
@OrangeTux Inilah kode yang dibongkar . Menggunakan metode yang disarankan ThomasH bahkan akan lebih lambat.
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
Simon Zimmermann
sumber
83
Yang ini menekankan tujuan utama dari operator ternary: pemilihan nilai. Ini juga menunjukkan bahwa lebih dari satu terner dapat dirantai bersama menjadi satu ekspresi.
Roy Tinker
6
@Craig, saya setuju, tetapi juga membantu untuk mengetahui apa yang akan terjadi ketika tidak ada tanda kurung. Dalam kode asli, saya juga akan cenderung memasukkan parens eksplisit.
Jon Coombs
159

Dari dokumentasi :

Ekspresi bersyarat (kadang-kadang disebut "operator ternary") memiliki prioritas terendah dari semua operasi Python.

Ekspresi x if C else ypertama mengevaluasi kondisi, C ( bukan x ); jika C benar, x dievaluasi dan nilainya dikembalikan; jika tidak, y dievaluasi dan nilainya dikembalikan.

Lihat PEP 308 untuk detail lebih lanjut tentang ekspresi kondisional.

Baru sejak versi 2.5.

Michael Burr
sumber
120

Operator untuk ekspresi kondisional dalam Python ditambahkan pada 2006 sebagai bagian dari Proposal Peningkatan Python 308 . Bentuknya berbeda dari ?:operator umum dan itu:

<expression1> if <condition> else <expression2>

yang setara dengan:

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

Berikut ini sebuah contoh:

result = x if a > b else y

Sintaks lain yang dapat digunakan (kompatibel dengan versi sebelum 2.5):

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

di mana operan dievaluasi dengan malas .

Cara lain adalah dengan mengindeks tupel (yang tidak konsisten dengan operator bersyarat dari sebagian besar bahasa lain):

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

atau kamus yang dibangun secara eksplisit:

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

Metode lain (kurang dapat diandalkan), tetapi lebih sederhana adalah menggunakan anddan oroperator:

result = (a > b) and x or y

Namun ini tidak akan berhasil jika xmau False.

Solusi yang mungkin adalah membuat xdan ymendaftar atau tupel sebagai berikut:

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

atau:

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

Jika Anda bekerja dengan kamus, alih-alih menggunakan kondisional terner, Anda dapat memanfaatkan get(key, default), misalnya:

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

Sumber: ?: Dalam Python di Wikipedia

kenorb
sumber
1
result = {1: x, 0: y}[a > b]adalah varian lain yang mungkin ( Truedan Falsesebenarnya bilangan bulat dengan nilai-nilai 1dan 0)
Walter Tross
98

Sayangnya

(falseValue, trueValue)[test]

solusi tidak memiliki perilaku hubung singkat; dengan demikian keduanya falseValuedan trueValuedievaluasi terlepas dari kondisinya. Ini bisa suboptimal atau bahkan buggy (yaitu keduanya trueValuedan falseValuebisa menjadi metode dan memiliki efek samping).

Salah satu solusi untuk ini adalah

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

(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 trueValuekesalahan " -evaluates-to-false" .

gorsky
sumber
2
Sementara tuple trik lambdas bekerja, dibutuhkan sekitar 3x selama operator ternary. Ini hanya akan menjadi ide yang masuk akal jika dapat menggantikan rantai panjang if else if.
Perkins
72

Operator ternary dalam Bahasa pemrograman yang berbeda

Di sini saya hanya mencoba untuk menunjukkan beberapa perbedaan penting di ternary operatorantara beberapa bahasa pemrograman.

Operator ternary dalam Javascript

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

Operator Ternary di Ruby

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

Operator ternary di Scala

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

Operator ternary dalam pemrograman R.

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

Operator ternary dengan Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
Simplans
sumber
5
Ini mungkin terdengar dikritik; tetapi apa yang pada dasarnya dikatakan adalah bahwa sintaksis Python cenderung dipahami oleh seseorang yang tidak pernah melihat operator ternary, sementara sangat sedikit orang akan memahami sintaksis yang lebih biasa kecuali mereka telah diberitahu terlebih dahulu apa artinya.
fralau
1
Algol68: a = .if. .benar. .kemudian. 1 .else. 0 .fi. Ini dapat dinyatakan juga a = (. True. | 1 | 0) Seperti biasa Algol68 adalah peningkatan dari penggantinya.
Albert van der Horst
63

Untuk Python 2.5 dan yang lebih baru ada sintaksis spesifik:

[on_true] if [cond] else [on_false]

Pada Python lama, operator ternary tidak diimplementasikan tetapi dimungkinkan untuk mensimulasikannya.

cond and on_true or on_false

Padahal, ada masalah potensial, yang jika conddievaluasi Truedan on_truedievaluasi Falsekemudian on_falsedikembalikan on_true. Jika Anda ingin perilaku ini metode ini OK, jika tidak gunakan ini:

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

yang bisa dibungkus dengan:

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

dan digunakan dengan cara ini:

q(cond, on_true, on_false)

Ini kompatibel dengan semua versi Python.

Paolo
sumber
2
Perilaku tidak identik - q("blob", on_true, on_false)pengembalian on_false, sedangkan on_true if cond else on_falsepengembalian on_true. Sebuah solusi adalah untuk menggantikan conddengan cond is not Nonedalam kasus ini, meskipun itu bukan solusi sempurna.
5
Mengapa tidak bool(cond)bukan cond is True? Yang pertama memeriksa kebenaran cond, yang terakhir memeriksa pointer-kesetaraan dengan Trueobjek. Seperti yang disorot oleh @AndrewCecil, "blob"itu benar tapi itu is not True.
Jonas Kölker
Wow, itu kelihatan sangat pekat! :) Secara teknis, Anda bahkan dapat menulis [on_false, on_True][cond is True]sehingga ekspresi menjadi lebih pendek.
Arseny
Tidak ada hubungan pendek dalam jawaban ini. Jika on_true dan on_false mahal untuk menelepon, ini adalah jawaban yang buruk.
Hucker
44

Anda mungkin sering menemukan

cond and on_true or on_false

tapi ini menyebabkan masalah ketika on_true == 0

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

di mana Anda harapkan untuk operator ternary normal hasil ini

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
Benoit Bertholon
sumber
38

Apakah Python memiliki operator kondisional ternary?

Iya. Dari file tata bahasa :

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

Bagian yang menarik adalah:

or_test ['if' or_test 'else' test]

Jadi, operasi kondisional ternary adalah dalam bentuk:

expression1 if expression2 else expression3

expression3akan dievaluasi dengan malas (yaitu, dievaluasi hanya jika expression2salah dalam konteks boolean). Dan karena definisi rekursif, Anda dapat rantai mereka tanpa batas (meskipun mungkin dianggap gaya yang buruk.)

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

Catatan tentang penggunaan:

Perhatikan bahwa setiap ifharus diikuti dengan else. 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:

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

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:

[expression1 for element in iterable if expression2]

expression2berfungsi 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 if expression1 else expression2

expression1harus 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 menggunakan orperilaku pintas:

expression1 or expression2

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.

Aaron Hall
sumber
1
expression1 or expression2menjadi serupa dan dengan kelemahan / positif yang sama seperti expression1 || expression2di javascript
JSDBroughton
1
Terima kasih, @selurvedu - ini bisa membingungkan sampai Anda menyelesaikannya. Saya belajar dengan cara yang sulit, jadi cara Anda mungkin tidak sesulit itu. ;) Menggunakan jika tanpa yang lain, pada akhir ekspresi generator atau pemahaman daftar akan memfilter iterable. Di depan, ini adalah operasi bersyarat terner, dan memerlukan yang lain. Bersulang!!
Aaron Hall
@ AaronHall Meskipun penggunaan metasyntactic Anda expressionNuntuk semua instance konsisten, mungkin lebih mudah untuk memahami dengan penamaan yang membedakan ekspresi uji kondisional dari dua ekspresi hasil; misalnya result1 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?
tchrist
@tchrist terima kasih atas ulasannya - jika Anda melihat riwayat revisi, pos ini saat ini memiliki dua revisi. Sebagian besar jawaban saya yang lain, terutama yang teratas, telah ditinjau kembali berulang kali. Jawaban ini tidak pernah menarik perhatian saya karena status wiki komunitas tidak memberi saya kredit untuk konten tersebut, jadi saya tidak pernah melihat suara di dalamnya. Karena saya tidak punya waktu untuk mengedit tentang ini sekarang, katak tahu kapan itu akan menjadi perhatian saya lagi di masa depan. Saya dapat melihat bahwa Anda telah mengedit jawaban teratas, jadi silakan meminjam / mengutip materi saya dari pos ini dalam artikel itu (dan mengutip saya jika tepat!)
Aaron Hall
23

Mensimulasikan operator terner python.

Sebagai contoh

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

keluaran:

'b greater than a'
Sasikiran Vaddi
sumber
Mengapa tidak sederhana. result = (y, x)[a < b]Mengapa Anda menggunakan lambdafungsi ?
Grijesh Chauhan
5
@GrijeshChauhan Karena pada ekspresi "compliated", misalnya melibatkan pemanggilan fungsi dll, ini akan dieksekusi dalam kedua kasus. Ini mungkin tidak diinginkan.
glglgl
20

Operator kondisional ternary hanya memungkinkan pengujian suatu kondisi dalam satu baris menggantikan multiline jika-jika membuat kode kompak.

Sintaks:

[on_true] jika [ekspresi] lain [on_false]

1- Metode Sederhana untuk menggunakan operator ternary:

# 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- Metode Langsung menggunakan tupel, Kamus, dan lambda:

# 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- Operator ternary dapat ditulis sebagai bersarang jika-ada:

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

Pendekatan di atas dapat ditulis sebagai:

# 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
Ali Hallaji
sumber
1
Perhatikan bahwa operator ternary lebih kecil (dalam memori) dan lebih cepat daripada jika bersarang. Selain itu, sarang Anda if-elsesebenarnya 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 ).
Perkins
19

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,

0 and exp

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

1 or exp

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

True and exp1 or exp2

Ekspresi kedua exp2 tidak akan dievaluasi karena True and exp1akan Benar ketika exp1 tidak salah.

Demikian pula dalam

False and exp1 or exp2

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] ;

Natesh bhat
sumber
Jika Anda ingin menggunakannya dalam konteks x = [condition] and ([expression_1] or 1) or [expression_2]dan expression_1mengevaluasi ke false, xakan 1, tidak expression_1. Gunakan jawaban yang diterima.
moi
18

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:

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

, menjadi:

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

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.

Todor
sumber
5
Saya lebih suka print( 'yes' if conditionX else 'nah' )daripada jawaban Anda. :-)
frederick99
Itu jika Anda ingin print()dalam kedua kasus - dan itu terlihat sedikit lebih pythonic, saya harus mengakui :) Tapi bagaimana jika ekspresi / fungsi tidak sama - seperti print('yes') if conditionX else True- untuk mendapatkan print()satu - satunya yang benarconditionX
Todor Minakov
Untuk menambah komentar Frederick99, alasan lain untuk menghindarinya print('yes') if conditionX else print('nah')adalah memberikan Sintaksis dalam Python2.
Thierry Lathuille
Satu-satunya alasan ia memberikan kesalahan sintaks adalah karena dalam cetak Python 2 adalah pernyataan - 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.
Todor Minakov
18
a if condition else b

Hafalkan piramida ini jika Anda kesulitan mengingat:

     condition
  if           else
a                   b 
shivtej
sumber
14

Salah satu alternatif untuk ekspresi kondisional Python

"yes" if boolean else "no"

adalah sebagai berikut:

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

yang memiliki ekstensi yang bagus berikut:

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

Alternatif terpendek tetap:

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

tetapi tidak ada alternatif untuk

yes() if boolean else no()

jika Anda ingin menghindari evaluasi yes() dan no() , karena dalam

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

keduanya no()dan yes()dievaluasi.

Walter Tross
sumber
10

Banyak bahasa pemrograman yang berasal dari Cbiasanya memiliki sintaksis dari operator kondisional ternary berikut:

<condition> ? <expression1> : <expression2>

Pada awalnya, Python B enevolent D ictator F atau L ife (Maksudku Guido van Rossum, tentu saja) ditolak (sebagai Pythonic non-style), karena cukup sulit untuk dipahami bagi orang-orang tidak digunakan untuk Cbahasa. Juga, tanda titik dua :sudah memiliki banyak kegunaan Python. Setelah PEP 308 disetujui, Pythonakhirnya menerima ekspresi kondisional pintasan sendiri (apa yang kita gunakan sekarang):

<expression1> if <condition> else <expression2>

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):

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

# Result is 'High'

Operator ternary dapat dirantai secara seri:

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

# Result is 'Normal'

Yang berikut ini sama dengan yang sebelumnya:

pressure = 5

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

# Result is 'Normal'

Semoga ini membantu.

ARGeo
sumber
10

Seperti yang sudah dijawab, ya ada operator ternary dengan python:

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

Informasi tambahan:

Jika <expression 1>kondisinya Anda dapat menggunakan evaluasi Short-cirquit :

a = True
b = False

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

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

PS: Tentu saja, evaluasi Short-cirquit bukan operator ternary tetapi sering ternary digunakan dalam kasus-kasus di mana korsleting cukup.

jujur
sumber
1
Suara positif untuk short-circuitevaluasi itu.
CodeIt
7

YA, python memiliki operator ternary, ini adalah sintaks dan kode contoh untuk menunjukkan yang sama :)

#[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")
PythonLover
sumber
Saya telah menambahkan contoh pernyataan satu baris untuk memeriksa nomor mana yang besar untuk menjelaskannya lebih lanjut
PythonLover
1
printbenar-benar bukan pilihan yang baik, karena ini akan memberikan SyntaxError di Python2.
Thierry Lathuille
@ Thierry Lathuille di sini saya menggunakan fungsi print () bukan print statement, fungsi print adalah untuk Python 3 sedangkan statement print adalah untuk Python 2
PythonLover
Pertanyaannya sudah ditanyakan pada SO, coba saja dengan Python 2 dan Anda akan melihatnya sendiri. 'print (' hello ') adalah sintaks yang benar-benar valid dalam Python 2.7, tetapi cara ini diuraikan membuat kode Anda di atas melempar SyntaxError.
Thierry Lathuille
2

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.

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

^ Ini adalah formulir panjang untuk melakukan penugasan tersebut.

Di bawah ini adalah bentuk terner. Tapi ini bukan cara yang paling ringkas - lihat contoh terakhir.

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

Dengan Python, Anda cukup menggunakan oruntuk tugas alternatif.

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

Karya-karya di atas, karena li1merupakan Nonedan memperlakukan interp bahwa sebagai False dalam ekspresi logika. Interp kemudian bergerak dan mengevaluasi ekspresi kedua, yang bukan Nonedan itu bukan daftar kosong - sehingga ditugaskan untuk.

Ini juga berfungsi dengan daftar kosong. Misalnya, jika Anda ingin menetapkan adaftar mana saja yang memiliki item.

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

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 astring mana pun yang tidak kosong.

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

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.

Todd
sumber
1

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_valuedengan nilai default jika tidak disetel:

run_algorithm(option_value if option_value is not None else 10)

atau sederhana

run_algorithm(option_value if option_value else 10)

Namun, solusi yang lebih baik adalah menulis

run_algorithm(option_value or 10)
pengguna118967
sumber
-2

jika variabel didefinisikan dan Anda ingin memeriksa apakah memiliki nilai Anda bisa saja 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)

akan menampilkan

no Input
no Input
no Input
hello
['Hello']
True
ewwink
sumber
1
Meskipun berguna untuk masalah yang serupa, ini bukan persyaratan terner. Ini berfungsi untuk menggantikan x if x else y, tetapi tidak x if z else y.
Perkins
-2

Cara yang rapi untuk menghubungkan beberapa operator:

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
Yaakov Bressler
sumber
-2

Saya menemukan rumit sintaks python default val = a if cond else b, jadi kadang-kadang saya melakukan ini:

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

Tentu saja, ini memiliki kelemahan dari selalu mengevaluasi kedua belah pihak (a dan b), tetapi sintaksnya jauh lebih jelas bagi saya

Baruc Almaguer
sumber
Ini tampaknya menjadi dua kali lipat jumlah pekerjaan, lebih banyak penggunaan RAM dan lebih dikaburkan daripada val = a if cond else bpernyataan yang lebih sederhana .
eatsfood
-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

itu bisa disarangkan sesuai kebutuhan Anda. semoga berhasil

**

Itu Enam
sumber