Saya memiliki skrip python yang dapat menerima argumen baris perintah nol atau tiga. (Entah itu berjalan pada perilaku default atau membutuhkan ketiga nilai yang ditentukan.)
Apa sintaks yang ideal untuk sesuatu seperti:
if a and (not b or not c) or b and (not a or not c) or c and (not b or not a):
?
python
if-statement
Chris Wilson
sumber
sumber
len(sys.argv)
akan selalu setidaknya 1: ini termasuk executable asargv[0]
.if not (a and b and c)
(nol arg), dan kemudianif a and b and c
(ketiga arg)Jawaban:
Jika Anda bermaksud bentuk minimal, ikuti ini:
Yang menerjemahkan judul pertanyaan Anda.
UPDATE: seperti yang dikatakan dengan benar oleh Volatility dan Supr, Anda dapat menerapkan hukum De Morgan dan mendapatkan yang setara:
Saran saya adalah menggunakan formulir apa pun yang lebih penting bagi Anda dan pemrogram lainnya. Yang pertama berarti "ada sesuatu yang salah, tetapi juga sesuatu yang benar" , yang kedua "Ada sesuatu yang benar, tetapi tidak semuanya" . Jika saya mengoptimalkan atau melakukan ini dalam perangkat keras, saya akan memilih yang kedua, di sini pilih saja yang paling mudah dibaca (juga dengan mempertimbangkan kondisi yang akan Anda uji dan nama mereka). Saya memilih yang pertama.
sumber
if not (a and b and c) and (a or b or c)
if (a or b or c) and not (a and b and c)
untuk menyamakan gelar dengan sempurna;)if any([a,b,c]) and not all([a,b,c])
Bagaimana tentang:
Varian lainnya:
sumber
sum(conditions)
dapat salah jika salah satu dari mereka kembali2
misalnya, yaituTrue
.sum(map(bool, conditions))
Pertanyaan ini sudah memiliki banyak jawaban yang sangat tinggi dan jawaban yang diterima, tetapi semuanya sejauh ini terganggu oleh berbagai cara untuk mengekspresikan masalah boolean dan melewatkan satu poin penting:
Logika ini seharusnya tidak menjadi tanggung jawab kode Anda , tetapi harus ditangani oleh
argparse
modul. Jangan repot-repot menulis pernyataan if kompleks, alih-alih lebih suka mengatur parser argumen Anda seperti ini:Dan ya, itu harus menjadi pilihan bukan argumen posisi, karena bagaimanapun juga opsional .
diedit: Untuk mengatasi kekhawatiran LarsH dalam komentar, di bawah ini adalah contoh bagaimana Anda bisa menulisnya jika Anda yakin Anda menginginkan antarmuka dengan 3 atau 0argumen posisi . Saya berpendapat bahwa antarmuka sebelumnya adalah gaya yang lebih baik, karenaargumen opsional harus menjadi pilihan , tapi inilah pendekatan alternatif demi kelengkapan. Catat kwarg utama
usage
saat membuat parser Anda, karenaargparse
akan secara otomatis menghasilkan pesan penggunaan yang menyesatkan!Berikut ini beberapa contoh penggunaan:
sumber
Saya akan pergi untuk:
Saya pikir ini harus korsleting yang cukup efisien
Penjelasan
Dengan membuat
conds
iterator, penggunaan pertamaany
akan hubungan pendek dan biarkan iterator menunjuk ke elemen berikutnya jika ada item yang benar; jika tidak, ia akan mengkonsumsi seluruh daftar dan menjadiFalse
. Berikutnyaany
mengambil item yang tersisa di iterable, dan memastikan daripada tidak ada nilai true lainnya ... Jika ada, seluruh pernyataan tidak mungkin benar, sehingga tidak ada satu elemen unik (sirkuit pendek begitu lagi). Yang terakhirany
akan kembaliFalse
atau akan menghabiskan iterable dan menjadiTrue
.catatan: pemeriksaan di atas memeriksa apakah hanya satu syarat yang ditetapkan
Jika Anda ingin memeriksa apakah satu atau lebih item, tetapi tidak setiap item ditetapkan, maka Anda dapat menggunakan:
sumber
[a, b, c] = [True, True, False]
tidak seharusnya kode Anda "dicetak"False
, sementara output yang diharapkanTrue
?iter
.any
danall
malas akan mengkonsumsi daftar, benar, tetapi daftar itu sudah sepenuhnya dievaluasi pada saat Anda sampai di sana!Kalimat bahasa Inggris:
Diterjemahkan ke logika ini:
Kata "tetapi" biasanya menyiratkan konjungsi, dengan kata lain "dan". Lebih jauh, "mereka semua" diterjemahkan menjadi gabungan dari kondisi: kondisi ini, dan kondisi itu, dan kondisi lainnya. The "not" membalikkan seluruh konjungsi itu.
Saya tidak setuju dengan jawaban yang diterima. Penulis lalai menerapkan interpretasi paling langsung ke spesifikasi, dan lalai menerapkan Hukum De Morgan untuk menyederhanakan ekspresi ke lebih sedikit operator:
sambil mengklaim bahwa jawabannya adalah "bentuk minimal".
sumber
Ini kembali
True
jika satu dan hanya satu dari tiga kondisiTrue
. Mungkin yang Anda inginkan dalam kode contoh Anda.sumber
Bagaimana dengan: (kondisi unik)
Perhatikan, jika Anda mengizinkan dua syarat juga, Anda bisa melakukannya
sumber
1 <= bool(a) + bool(b) + bool(c) <= 2
.Agar lebih jelas, Anda ingin membuat keputusan berdasarkan berapa banyak parameter yang BENAR (dalam kasus argumen string - bukan kosong)?
Lalu Anda membuat keputusan:
Sekarang logikanya lebih jelas.
sumber
Dan mengapa tidak menghitungnya saja?
sumber
Jika Anda tidak keberatan menjadi sedikit samar Anda bisa simly roll dengan
0 < (a + b + c) < 3
yang akan kembalitrue
jika Anda memiliki antara satu dan dua pernyataan benar dan salah jika semuanya salah atau tidak ada yang salah.Ini juga menyederhanakan jika Anda menggunakan fungsi untuk mengevaluasi bools karena Anda hanya mengevaluasi variabel satu kali dan yang berarti Anda dapat menulis fungsi inline dan tidak perlu menyimpan sementara variabel. (Contoh:.
0 < ( a(x) + b(x) + c(x) ) < 3
)sumber
Pertanyaannya menyatakan bahwa Anda memerlukan ketiga argumen (a dan b dan c) atau tidak satupun (tidak (a atau b atau c))
Ini memberi:
(a dan b dan c) atau tidak (a atau b atau c)
sumber
Seperti yang saya pahami, Anda memiliki fungsi yang menerima 3 argumen, tetapi jika tidak, itu akan berjalan pada perilaku default. Karena Anda belum menjelaskan apa yang harus terjadi ketika 1 atau 2 argumen diberikan, saya akan menganggap itu hanya melakukan perilaku default. Dalam hal ini, saya pikir Anda akan menemukan jawaban berikut sangat menguntungkan:
Namun, jika Anda ingin 1 atau 2 argumen ditangani secara berbeda:
catatan: Ini mengasumsikan bahwa
False
nilai " " tidak akan diteruskan ke metode ini.sumber
Jika Anda bekerja dengan iterator kondisi, bisa jadi lambat untuk diakses. Tetapi Anda tidak perlu mengakses setiap elemen lebih dari sekali, dan Anda tidak selalu perlu membaca semuanya. Inilah solusi yang akan bekerja dengan generator yang tak terbatas:
sumber
Ketika setiap keterberian
bool
adalahTrue
, atau ketika setiap keterberianbool
adalahFalse
...mereka semua sama satu sama lain!
Jadi, kita hanya perlu menemukan dua elemen yang mengevaluasi
bool
s yang berbedauntuk mengetahui bahwa setidaknya ada satu
True
dan setidaknya satuFalse
.Solusi singkat saya:
Saya percaya itu hubungan arus pendek, karena AFAIK
a==b==c
samaa==b and b==c
.Solusi umum saya:
Saya juga menulis beberapa kode yang berhubungan dengan beberapa iterables, tetapi saya menghapusnya dari sini karena saya pikir tidak ada gunanya. Namun itu masih tersedia di sini .
sumber
Ini pada dasarnya adalah fungsi "beberapa (tetapi tidak semua)" (bila dibandingkan dengan
any()
danall()
builtin).Ini menyiratkan bahwa harus ada
False
s danTrue
s di antara hasilnya. Karena itu, Anda dapat melakukan hal berikut:Salah satu keuntungan dari kode ini adalah Anda hanya perlu melakukan iterasi satu kali melalui item (boolean) yang dihasilkan.
Salah satu kelemahan adalah bahwa semua kebenaran-ekspresi ini selalu dievaluasi, dan tidak melakukan hubungan arus pendek seperti
or
/and
operator.sumber
.issuperset
daripada hanya memeriksa panjang 2,bool
tidak bisa mengembalikan apa pun selain Benar dan Salah. Mengapa menetapkan lambda (baca: fungsi anonim) untuk nama alih-alih hanya menggunakan def?return
jika Anda menggunakandef
. Saya pikir secara umum solusi ini bagus. tidak perlu membatasi diri pada boolean, pertanyaannya pada dasarnya adalah "bagaimana cara memastikan semua elemen ini muncul dalam daftar saya". mengapaset
jika Anda tidak membutuhkan mutabilitas? lebih banyak kekekalan selalu lebih baik jika Anda tidak membutuhkan kinerja.tee
itertools.tee
tetapi 1) Saya sedang mencari satu-liner yang sederhana / cukup kecil untuk menjamin copy-paste, 2) Anda sudah memberikan jawaban yang menggunakan teknik itu :-)