Saya mencoba membuat fungsi yang akan membandingkan banyak variabel dengan integer dan menghasilkan string tiga huruf. Saya bertanya-tanya apakah ada cara untuk menerjemahkan ini ke Python. Jadi katakan:
x = 0
y = 1
z = 3
mylist = []
if x or y or z == 0 :
mylist.append("c")
if x or y or z == 1 :
mylist.append("d")
if x or y or z == 2 :
mylist.append("e")
if x or y or z == 3 :
mylist.append("f")
yang akan mengembalikan daftar:
["c", "d", "f"]
Apakah hal seperti ini mungkin?
python
if-statement
comparison
match
boolean-logic
pengguna1877442
sumber
sumber
1
dalam (tuple)any
/all
fungsi. Sebagai contoh:all([1, 2, 3, 4, False])
akan mengembalikan Falseall([True, 1, 2, 3])
akan kembali Trueany([False, 0, 0, False])
akan kembali Falseany([False, 0, True, False])
akan kembali Benarif x == 0 or 1:
, yang tentu saja miripif x or y == 0:
, tetapi mungkin sedikit membingungkan bagi pemula. Mengingat volume tipis "Mengapa saya tidakx == 0 or 1
bekerja?" pertanyaan, saya lebih suka menggunakan pertanyaan ini sebagai target duplikat kanonik kami untuk pertanyaan ini.0
,0.0
atauFalse
. Anda dapat dengan mudah menulis kode yang salah yang memberikan jawaban "benar".Jawaban:
Anda salah mengerti bagaimana ekspresi boolean bekerja; mereka tidak bekerja seperti kalimat bahasa Inggris dan kira Anda berbicara tentang perbandingan yang sama untuk semua nama di sini. Anda mencari:
x
dany
sebaliknya dievaluasi sendiri (False
jika0
,True
sebaliknya).Anda dapat mempersingkat hal itu menggunakan uji penahanan terhadap tuple :
atau lebih baik lagi:
menggunakan sebuah
set
untuk mengambil keuntungan dari tes keanggotaan konstan-biaya (in
mengambil jumlah waktu yang tetap apapun kiri operan adalah).Saat Anda menggunakan
or
, python melihat setiap sisi operator sebagai ekspresi terpisah . Ekspresix or y == 1
diperlakukan sebagai tes boolean pertama untukx
, maka jika itu Salah, ekspresiy == 1
diuji.Ini karena prioritas operator . The
or
operator memiliki prioritas lebih rendah dari==
tes, jadi yang terakhir dievaluasi pertama .Namun, bahkan jika ini bukan masalahnya, dan ekspresi
x or y or z == 1
sebenarnya ditafsirkan sebagai(x or y or z) == 1
gantinya, ini masih tidak akan melakukan apa yang Anda harapkan.x or y or z
akan mengevaluasi argumen pertama yang 'benar', misalnya tidakFalse
, angka 0 atau kosong (lihat ekspresi boolean untuk detail tentang apa yang Python anggap salah dalam konteks boolean).Jadi untuk nilai-nilai
x = 2; y = 1; z = 0
,x or y or z
akan memutuskan untuk2
, karena itu adalah nilai true-like pertama dalam argumen. Maka2 == 1
akan menjadiFalse
, meskipuny == 1
akanTrue
.Hal yang sama berlaku untuk kebalikannya; menguji beberapa nilai terhadap satu variabel;
x == 1 or 2 or 3
akan gagal karena alasan yang sama. Gunakanx == 1 or x == 2 or x == 3
ataux in {1, 2, 3}
.sumber
set
versi. Tuple's sangat murah untuk dibuat dan digunakan kembali. Pada mesin saya setidaknya, tuple lebih cepat daripada set asalkan ukuran tuple sekitar 4-8 elemen. Jika Anda harus memindai lebih dari itu, gunakan satu set, tetapi jika Anda mencari item dari 2-4 kemungkinan, tuple masih lebih cepat! Jika Anda dapat mengatur untuk yang paling mungkin kasus menjadi yang pertama dalam tupel, menang bahkan lebih besar: (pengujian saya:timeit.timeit('0 in {seq}'.format(seq=tuple(range(9, -1, -1))))
)set
notasi literal untuk tes ini bukan penghematan kecuali isiset
literal juga literal, bukan?if 1 in {x, y, z}:
tidak dapat men-cacheset
, karenax
,y
danz
bisa berubah, jadi salah satu solusi perlu membanguntuple
atauset
dari awal, dan saya curiga penghematan pencarian apa pun yang mungkin Anda dapatkan ketika memeriksa keanggotaan akan dibanjiri olehset
waktu pembuatan yang lebih besar .in [...]
atauin {...}
) hanya berfungsi jika konten daftar atau set juga literal yang tidak dapat diubah.Masalah Anda lebih mudah diatasi dengan struktur kamus seperti:
sumber
d = "cdef"
yang mengarah keMyList = ["cdef"[k] for k in [x, y, z]]
map(lambda i: 'cdef'[i], [x, y, z])
[x, y, z]
Sebagaimana dinyatakan oleh Martijn Pieters, format yang benar dan tercepat adalah:
Menggunakan sarannya Anda sekarang akan memiliki pernyataan if terpisah sehingga Python akan membaca setiap pernyataan apakah pernyataan sebelumnya adalah
True
atauFalse
. Seperti:Ini akan berhasil, tetapi jika Anda merasa nyaman menggunakan kamus (lihat apa yang saya lakukan di sana), Anda dapat membersihkan ini dengan membuat kamus awal yang memetakan angka ke huruf yang Anda inginkan, kemudian hanya menggunakan for-loop:
sumber
Cara langsung untuk menulis
x or y or z == 0
adalahTapi saya tidak berpikir, Anda menyukainya. :) Dan cara ini jelek.
Cara lain (yang lebih baik) adalah:
Banyak BTW
if
s dapat ditulis sebagai sesuatu seperti inisumber
dict
alih - alih kunci, Anda akan mendapatkan kesalahan karena nilai baliknya.append
adalahNone
, dan panggilanNone
memberi sebuahAttributeError
. Secara umum saya setuju dengan metode ini.filter
akan lebih baik daripadamap
, karena hanya akan mengembalikan contoh di mana lambda menilai trueany(v == 0 for v in (x, y, z))
Jika Anda sangat malas, Anda bisa meletakkan nilai-nilai di dalam array. Seperti
Anda juga dapat memasukkan angka dan huruf ke dalam kamus dan melakukannya, tetapi ini mungkin BANYAK lebih rumit daripada sekadar pernyataan. Itulah yang Anda dapatkan karena berusaha menjadi sangat malas :)
Satu hal lagi, milikmu
akan dikompilasi, tetapi tidak dengan cara yang Anda inginkan. Ketika Anda cukup meletakkan variabel dalam pernyataan if (contoh)
program akan memeriksa apakah variabelnya bukan nol. Cara lain untuk menulis pernyataan di atas (yang lebih masuk akal) adalah
Bool adalah fungsi inbuilt dalam python yang pada dasarnya melakukan perintah memverifikasi pernyataan boolean (Jika Anda tidak tahu apa itu, itu adalah apa yang Anda coba buat dalam pernyataan if Anda sekarang :))
Cara malas lain yang saya temukan adalah:
sumber
list
adalah built-in Python; gunakan nama lain saja, sepertixyz
misalnya. Mengapa Anda membuat daftar dalam empat langkah ketika Anda bisa melakukannya, yaituxyz = [x, y, z]
? Jangan gunakan daftar paralel, gunakan dict sebagai gantinya. Secara keseluruhan, solusi ini jauh lebih berbelit-belit daripada milik ThatGuyRussell . Juga untuk bagian terakhir, mengapa tidak melakukan pemahaman, yaituany(v == 0 for v in (x, y, z))
? Juga array adalah sesuatu yang lain di Python.Untuk memeriksa apakah suatu nilai terkandung dalam seperangkat variabel, Anda dapat menggunakan modul inbuilt
itertools
danoperator
.Sebagai contoh:
Impor:
Deklarasikan variabel:
Buat pemetaan nilai (sesuai urutan yang ingin Anda periksa):
Gunakan
itertools
untuk memungkinkan pengulangan variabel:Akhirnya, gunakan
map
fungsi untuk membuat iterator:Kemudian, ketika memeriksa nilai-nilai (dalam urutan asli), gunakan
next()
:dll ...
Ini memiliki keunggulan dibandingkan
lambda x: x in (variables)
karenaoperator
modul inbuilt dan lebih cepat dan lebih efisien daripada menggunakanlambda
yang harus membuat fungsi kustom di tempat.Opsi lain untuk memeriksa apakah ada nilai bukan nol (atau salah) dalam daftar:
Setara:
sumber
Set adalah pendekatan yang baik di sini, karena memerintahkan variabel, apa yang tampaknya menjadi tujuan Anda di sini.
{z,y,x}
adalah{0,1,3}
apa urutan parameter.Dengan cara ini, seluruh solusi adalah O (n).
sumber
Semua jawaban bagus yang disediakan di sini berkonsentrasi pada persyaratan spesifik dari poster asli dan berkonsentrasi pada
if 1 in {x,y,z}
solusi yang diajukan oleh Martijn Pieters.Apa yang mereka abaikan adalah implikasi yang lebih luas dari pertanyaan:
Bagaimana cara menguji satu variabel terhadap beberapa nilai?
Solusi yang diberikan tidak akan berfungsi untuk hit parsial jika menggunakan string misalnya:
Uji apakah string "Wild" berada dalam beberapa nilai
atau
untuk skenario ini, paling mudah mengkonversi ke string
Namun perlu dicatat, sebagaimana disebutkan oleh
@codeforester
, bahwa batasan kata hilang dengan metode ini, seperti pada:3 huruf
rot
memang ada dalam kombinasi dalam daftar tetapi tidak sebagai kata individual. Menguji "busuk" akan gagal tetapi jika salah satu item daftar "membusuk di neraka", itu akan gagal juga.Hasilnya, berhati-hatilah dengan kriteria pencarian Anda jika menggunakan metode ini dan ketahuilah bahwa itu memang memiliki batasan ini.
sumber
Saya pikir ini akan menanganinya dengan lebih baik:
Keluaran:
sumber
Jika Anda ingin menggunakan if, pernyataan lain berikut ini adalah solusi lain:
sumber
sumber
Kode ini mungkin bermanfaat
sumber
Anda dapat mencoba metode yang ditunjukkan di bawah ini. Dalam metode ini, Anda akan memiliki kebebasan untuk menentukan / memasukkan jumlah variabel yang ingin Anda masukkan.
sumber
Solusi satu baris:
Atau:
sumber
Mungkin Anda perlu rumus langsung untuk bit output yang ditetapkan.
Mari kita petakan ke bit:
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Hubungan isc (is 'c'):
Gunakan matematika jika rumus https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315
[c]:
(xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))
[d]:
((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))
...
Hubungkan formula ini dengan logika berikut:
and
adalah jumlah kuadrat dari persamaanor
adalah produk dari persamaandan Anda akan memiliki jumlah persamaan total express dan Anda memiliki total rumus jumlah
lalu jumlah & 1 adalah c, jumlah & 2 adalah d, jumlah & 4 adalah e, jumlah & 5 adalah f
Setelah ini, Anda dapat membentuk array standar di mana indeks elemen string akan sesuai dengan string siap.
array[sum]
memberi Anda string.sumber
Ini bisa dilakukan dengan mudah
sumber
Cara paling mnemonik untuk merepresentasikan kode semu Anda dengan Python adalah:
sumber
if any(v >= 42 for v in (x, y, z)):
). Dan kinerja semua 3 metode (2 in {x,y,z}
,2 in (x,y,z)
,any(_v == 2 for _v in (x,y,z))
) tampaknya hampir sama di CPython3.6 (lihat Intisari )Untuk menguji beberapa variabel dengan satu nilai tunggal:
if 1 in {a,b,c}:
Untuk menguji beberapa nilai dengan satu variabel:
if a in {1, 2, 3}:
sumber
Sepertinya Anda sedang membangun semacam cipher Caesar.
Pendekatan yang lebih umum adalah:
output
Tidak yakin apakah itu efek samping yang diinginkan dari kode Anda, tetapi urutan output Anda akan selalu diurutkan.
Jika ini yang Anda inginkan, baris terakhir dapat diubah menjadi:
sumber
Anda dapat menggunakan kamus:
sumber
Tanpa dikte, coba solusi ini:
dan memberi:
sumber
Ini akan membantu Anda.
sumber
Anda bisa menyatukan ini
dalam satu variabel.
Ubah kondisi kami sebagai:
Keluaran:
sumber
Masalah
Sedangkan pola untuk pengujian beberapa nilai
sangat mudah dibaca dan bekerja dalam banyak situasi, ada satu perangkap:
Tapi kami ingin memilikinya
Larutan
Satu generalisasi dari ungkapan sebelumnya didasarkan pada jawaban dari ytpillai :
yang dapat ditulis sebagai
Meskipun ungkapan ini mengembalikan hasil yang tepat, itu tidak dapat dibaca seperti ungkapan pertama :-(
sumber