Pertanyaan Apakah Python memiliki operator kondisional terner?


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


4427


asal


Jawaban:


Ya itu ditambahkan dalam versi 2.5.
Sintaksnya adalah:

a if condition else b

Pertama condition dievaluasi, lalu juga a atau b dikembalikan berdasarkan pada Boolean Nilai dari condition
Jika condition mengevaluasi ke Benar  a dikembalikan, yang lain b dikembalikan.

Sebagai contoh:

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

Perhatikan bahwa conditional adalah suatu ekspresi, tidak a pernyataan. Ini berarti Anda tidak dapat menggunakan tugas atau pass atau pernyataan lain dalam kondisi bersyarat:

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

Dalam kasus seperti itu, Anda harus menggunakan yang normal if pernyataan bukannya bersyarat.


Perlu diingat bahwa itu disukai oleh beberapa Pythonistas karena beberapa alasan:

  • Urutan argumen berbeda dari banyak bahasa lain (seperti C, Ruby, Java, dll.), Yang dapat menyebabkan bug ketika orang-orang tidak terbiasa dengan perilaku Python "mengejutkan" menggunakannya (mereka dapat membalik urutan).
  • Ada yang menganggapnya "berat", karena bertentangan dengan alur pemikiran normal (memikirkan kondisi dulu dan kemudian efeknya).
  • Alasan gaya.

Jika Anda mengalami kesulitan mengingat pesanan, maka ingatlah bahwa jika Anda membacanya dengan keras, Anda (hampir) mengatakan apa yang Anda maksud. Sebagai contoh, x = 4 if b > 8 else 9 dibaca dengan keras sebagai x will be 4 if b is greater than 8 otherwise 9.

Dokumentasi resmi:


5285



Anda dapat mengindeks ke tuple:

(falseValue, trueValue)[test]

test harus kembali Benar atau Salah.
Mungkin lebih aman untuk selalu menerapkannya sebagai:

(falseValue, trueValue)[test == True]

atau Anda dapat menggunakan built-in bool() untuk memastikan Boolean nilai:

(falseValue, trueValue)[bool(<expression>)]

591



Untuk versi sebelum 2.5, ada triknya:

[expression] and [on_true] or [on_false]

Itu bisa memberi hasil yang salah saat on_true   memiliki nilai boolean palsu.1
Meskipun itu memiliki manfaat mengevaluasi ekspresi kiri ke kanan, yang lebih jelas menurut saya.

1 Apakah ada yang setara dengan C ”?:” Operator terner?


245



expression1 jika kondisi lain expression2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1

155



Dari dokumentasi:

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

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

Lihat PEP 308 untuk detail lebih lanjut tentang ekspresi bersyarat.

Baru sejak versi 2.5.


105



Operator untuk ekspresi kondisional dengan Python ditambahkan pada tahun 2006 sebagai bagian dari Python Enhancement Proposal 308. Bentuknya berbeda dari biasa ?: operator dan itu:

<expression1> if <condition> else <expression2>

yang setara dengan:

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

Berikut ini contohnya:

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 operand berada malas dievaluasi.

Cara lain adalah dengan mengindeks tuple (yang tidak konsisten dengan operator kondisional sebagian besar bahasa lain):

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

atau kamus yang dikonstruksi secara eksplisit:

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

Metode lain (kurang dapat diandalkan), tetapi lebih sederhana adalah menggunakan and dan or operator:

result = (a > b) and x or y

Namun ini tidak akan berhasil jika x akan menjadi False.

Solusi yang mungkin adalah untuk membuatnya x dan y daftar atau tupel seperti 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 memanfaatkannya get(key, default), sebagai contoh:

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

Sumber: ?: dengan Python di Wikipedia


78



@naik:

Sayangnya

(falseValue, trueValue)[test]

solusi tidak memiliki perilaku hubungan pendek; dengan demikian baik nilai false dan trueValue dievaluasi terlepas dari kondisinya. Ini bisa menjadi suboptimal atau bahkan buggy (yaitu trueValue dan falseValue bisa berupa metode dan memiliki efek samping).

Satu solusi untuk ini adalah

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

(eksekusi tertunda sampai pemenang diketahui;)), tetapi memperkenalkan ketidakkonsistenan antara objek yang dapat dipanggil dan yang tidak dapat dipanggil. Selain itu, tidak menyelesaikan kasus saat menggunakan properti.

Dan begitulah ceritanya - memilih di antara 3 solusi yang disebutkan adalah trade-off antara memiliki fitur hubung singkat, menggunakan setidaknya python 2.5 (IMHO bukan masalah lagi) dan tidak rentan terhadap "trueValue-evaluates-to-false" kesalahan.


72



Untuk Python 2.5 dan yang lebih baru, ada sintaks khusus:

[on_true] if [cond] else [on_false]

Pada Pythons yang lebih tua, operator terner tidak diimplementasikan tetapi mungkin untuk mensimulasikannya.

cond and on_true or on_false

Padahal, ada potensi masalah, yang jika cond mengevaluasi ke True dan on_true mengevaluasi ke False kemudian on_false dikembalikan, bukan 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 dapat dibungkus oleh:

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

dan menggunakan cara ini:

q(cond, on_true, on_false)

Ini kompatibel dengan semua versi Python.


48