Bagaimana Anda mendapatkan xor logis dari dua variabel dengan Python?
Sebagai contoh, saya memiliki dua variabel yang saya harapkan menjadi string. Saya ingin menguji bahwa hanya satu dari mereka yang berisi nilai True (bukan None atau string kosong):
str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
print "bad"
The ^
Operator tampaknya bitwise, dan tidak didefinisikan pada semua objek:
>>> 1 ^ 1
0
>>> 2 ^ 1
3
>>> "abc" ^ ""
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ^: 'str' and 'str'
python
logical-operators
Zach Hirsch
sumber
sumber
a xor a
didefinisikan sebagai(a and not b) or (not a and b)
, dan karenanyaa xor b
, kapana
danb
apakah karakter string, atau tipe lainnya, akan menghasilkan apa pun yang(a and not b) or (not a and b)
dihasilkan.Jawaban:
Jika Anda sudah menormalkan input ke boolean, maka! = Adalah xor.
sumber
bool(a) is not bool(b)
?Anda selalu dapat menggunakan definisi xor untuk menghitungnya dari operasi logis lainnya:
Tapi ini agak terlalu bertele-tele bagi saya, dan pada pandangan pertama tidak terlalu jelas. Cara lain untuk melakukannya adalah:
Operator xor pada dua boolean adalah xor logis (tidak seperti pada int, di mana bitwise). Yang masuk akal, karena
bool
hanya subkelas dariint
, tetapi diimplementasikan untuk hanya memiliki nilai0
dan1
. Dan xor logis setara dengan xor bitwise ketika domain dibatasi untuk0
dan1
.Jadi
logical_xor
fungsi akan diimplementasikan seperti:Penghargaan untuk Nick Coghlan di milis Python-3000 .
sumber
(not b and a) or (not a and b)
sehingga mengembalikan string jika ada, yang sepertinya cara pythonic untuk fungsi untuk beroperasi.Bitwise eksklusif-atau sudah ada di dalam Python, dalam
operator
modul (yang identik dengan^
operator):sumber
xor(1, 2)
pengembalian3
. Dari dokumentasi:xor(a, b) -- Same as a ^ b.
Ingatlah bahwa apa pun yang diimpor darioperator
hanya bentuk fungsional dari operator infiks bawaan yang ada.bool
Jenis kelebihan__xor__
untuk mengembalikan boolean. Ini akan bekerja dengan baik, tetapi berlebihan ketikabool(a) ^ bool(b)
melakukan hal yang persis sama.^
Operator memanggil secara__xor__
internal.bool
tipe mengimplementasikan__xor__
metode khusus karena^
menyebutnya . Intinya adalah bahwabool(a) ^ bool(b)
berfungsi dengan baik, tidak perlu menggunakanoperator.xor()
fungsi di sini.Seperti yang dijelaskan Zach , Anda dapat menggunakan:
Secara pribadi, saya menyukai dialek yang sedikit berbeda:
Dialek ini terinspirasi dari bahasa diagram diagram logis yang saya pelajari di sekolah tempat "ATAU" dilambangkan dengan kotak yang berisi
≥1
(lebih besar atau sama dengan 1) dan "XOR" dilambangkan dengan kotak yang berisi=1
.Ini memiliki keuntungan menerapkan dengan benar eksklusif atau pada beberapa operan.
sumber
(((((True + True)==1)+False)==1)+True)==1
. Jawaban yang diberikan di sini benar-benar digeneralisasikan ke beberapa operan.True + True + False + True
, Anda jangan mendapatkan3
, danTrue + True + False + True == 3
memberikan kembaliTrue
sementaraTrue + True + False + True == 1
memberikan kembaliFalse
. Dengan kata lain, jawabannya di sini tidak digeneralisasi dengan benar; untuk itu, Anda perlu melakukan pekerjaan tambahan. Sementara ituTrue ^ True ^ False ^ True
pekerjaan sederhana seperti yang diharapkan.True
, XOR multi-arity. Ini adalah operasi yang berbeda dari, misalnyaA XOR B XOR ... XOR Z
,. Dengan kata lain, jika Anda berencana untuk menggunakan versi berbasis tambahan, maka setelah dikirimkan operanTrue + True + False + True
Anda harus mengharapkan hasilnyaFalse
karena lebih dari satu dari ituTrue
, yang berfungsi jika kondisi memeriksa== 1
.or
:A or B
: kembaliA
jikabool(A)
yaituTrue
, jika tidak kembaliB
and
::A and B
mengembalikanA
jikabool(A)
adaFalse
, jika tidak kembaliB
Untuk menjaga sebagian besar cara berpikir itu, definisi logis saya adalah:
Dengan cara itu dapat kembali
a
,b
atauFalse
:sumber
and
danor
tidak akan mengembalikan nilai logis.'foo' and 'bar'
kembali'bar'
...xor
implementasi yang konsisten dengan built-inand
danor
. Namun, tentu saja, dalam situasi praktis,bool(a) ^ bool(b)
atau bahkana ^ b
(jikaa
danb
diketahuibool
) tentu saja lebih ringkas.Saya telah menguji beberapa pendekatan dan
not a != (not b)
tampaknya menjadi yang tercepat.Berikut ini beberapa tes
Sunting: Contoh 1 dan 3 di atas tidak ada tanda kurung sehingga hasilnya salah. Hasil +
truth()
fungsi baru seperti yang disarankan ShadowRanger.sumber
from operator import truth
di bagian atas modul, dan mengujitruth(a) != truth(b)
.bool
menjadi konstruktor memiliki banyak overhead yang tidak terhindarkan pada level C (harus menerima argumen yang setara*args, **kwargs
dan menguraikantuple
dandict
mengekstraknya), di manatruth
(menjadi fungsi) dapat menggunakan jalur yang dioptimalkan yang tidak memerlukan salah satutuple
atau adict
, dan berjalan sekitar setengah dari waktubool
solusi berbasis (tetapi masih lebih lama darinot
solusi berbasis).Utas penghargaan:
Ide anoder ... Hanya Anda mencoba (mungkin) ekspresi pythonic «tidak» untuk mendapatkan perilaku logis «xor»
Tabel kebenarannya adalah:
Dan untuk string contoh Anda:
Namun; seperti yang mereka sebutkan di atas, itu tergantung pada perilaku aktual yang ingin Anda tarik tentang string pasangan mana pun, karena string bukan bolean ... dan bahkan lebih: jika Anda «Menyelam Ke Python» Anda akan menemukan «Sifat Aneh" dan "dan" atau "» http://www.diveintopython.net/power_of_introspection/and_or.html
Maaf saya menulis bahasa Inggris, ini bukan bahasa kelahiran saya.
Salam.
sumber
Python memiliki operator eksklusif-ATAU bitwise, yaitu
^
:Anda dapat menggunakannya dengan mengonversi input ke boolean sebelum menerapkan xor (
^
):(Diedit - terima kasih Arel)
sumber
^
adalah bitor xor (bukan xor logis seperti pertanyaan yang diajukan).bool(2) ^ bool(3)
memberikan jawaban yang berbeda daribool(2 ^ 3)
.a ^ b
adalah polimorf. Jikaa
danb
adalahbool
contoh, hasilnya juga akanbool
baik. Perilaku ini hampir tidak dapat disebut "bitwise" xor.^
sebagai bitwise, meskipun itu hal yang menarik yang jenis yang diawetkan untukbool
danint
jenis. Catatan:True ^ 2
adalah3
, menunjukkan bagaimana itu memang bitwise.bool ^ int
ini semacam memberikan segalanya untuk yangint
pertama. Namun, Python telah built-in dengan^
operator yang selama bertahun-bit dalamint
dan untuk satu bit diwakili dalambool
, sehingga keduanya bitwise , tetapi bitwise XOR untuk satu bit hanya adalah yang logis xor untuk boolean.xor
, berasal dari latar belakang teknik, bagi saya ini secara naluriah terasa seperti kekuatan matematika, yaitu2^3 = pow(2,3)
yang berarti saya selalu secara eksplisit berkomentar untuk mencegah kebingungan.Karena saya tidak melihat varian sederhana dari xor menggunakan argumen variabel dan hanya operasi pada nilai-nilai Kebenaran Benar atau Salah, saya hanya akan melemparkannya ke sini untuk digunakan orang lain. Ini seperti dicatat oleh orang lain, cukup (tidak untuk mengatakan sangat) langsung.
Dan penggunaannya juga mudah:
Karena ini adalah XOR n-ary logis yang digeneralisasikan, nilai kebenarannya akan Benar setiap kali jumlah operan Benar ganjil (dan tidak hanya ketika tepat satu yang Benar, ini hanya satu kasus di mana n-ary XOR adalah Benar).
Jadi jika Anda mencari predikat n-ary yang hanya Benar ketika salah satu operannya benar, Anda mungkin ingin menggunakan:
sumber
(bool(False) is False) == True
. Anda bisa menggunakannyaFalse
pada baris tersebut.Eksklusif Atau didefinisikan sebagai berikut
sumber
and
danor
lakukan hubungan arus pendek. Setiapxor
pelaksanaan tidak bisa arus pendek, sehingga sudah ada ketidaksesuaian; oleh karena itu, tidak ada alasan yangxor
harus beroperasi sepertiand
+or
lakukan.Kadang-kadang saya menemukan diri saya bekerja dengan 1 dan 0 bukannya boolean nilai Benar dan Salah. Dalam hal ini xor dapat didefinisikan sebagai
yang memiliki tabel kebenaran berikut:
sumber
Saya tahu ini terlambat, tetapi saya punya pemikiran dan mungkin layak, hanya untuk dokumentasi. Mungkin ini akan berhasil:
np.abs(x-y)
Idenya adalah itusumber
Sederhana, mudah dimengerti:
Jika pilihan eksklusif adalah yang Anda cari, itu dapat diperluas ke beberapa argumen:
sumber
sum(map(bool, y)) % 2 == 1
Bagaimana dengan ini?
akan memberi
a
jikab
salahakan memberi
b
jikaa
salahakan memberi
False
sebaliknyaAtau dengan ekspresi terner Python 2.5+:
sumber
Beberapa implementasi yang disarankan di sini akan menyebabkan evaluasi berulang operan dalam beberapa kasus, yang dapat menyebabkan efek samping yang tidak diinginkan dan karenanya harus dihindari.
Yang mengatakan,
xor
implementasi yang mengembalikan salah satuTrue
atauFalse
cukup sederhana; yang mengembalikan salah satu operan, jika mungkin, jauh lebih rumit, karena tidak ada konsensus mengenai operan mana yang harus dipilih, terutama ketika ada lebih dari dua operan. Misalnya, harusxor(None, -1, [], True)
kembaliNone
,[]
atauFalse
? Saya yakin setiap jawaban bagi sebagian orang tampak sebagai yang paling intuitif.Untuk hasil Benar atau Salah, ada sebanyak lima pilihan yang mungkin: kembalikan operan pertama (jika cocok dengan hasil akhir dalam nilai, atau boolean), kembalikan kecocokan pertama (jika setidaknya ada satu, boolean lain), kembalikan operan terakhir (jika ... lain ...), kembalikan pertandingan terakhir (jika ... lain ...), atau selalu kembalikan boolean. Secara keseluruhan, itu 5 ** 2 = 25 rasa
xor
.sumber
Banyak orang, termasuk saya, membutuhkan
xor
fungsi yang berperilaku seperti n-input xor circuit, di mana n adalah variabel. (Lihat https://en.wikipedia.org/wiki/XOR_gate ). Fungsi sederhana berikut mengimplementasikan ini.Contoh I / O berikut:
sumber
Untuk mendapatkan xor logis dari dua atau lebih variabel dalam Python:
^
atauoperator.xor
)Sebagai contoh,
Ketika Anda mengonversi input menjadi booleans, bitwise xor menjadi xor logis .
Perhatikan bahwa jawaban yang diterima salah:
!=
tidak sama dengan xor dengan Python karena kehalusan chaining operator .Misalnya, xor dari tiga nilai di bawah salah ketika menggunakan
!=
:(PS Saya mencoba mengedit jawaban yang diterima untuk memasukkan peringatan ini, tetapi perubahan saya ditolak.)
sumber
Sangat mudah ketika Anda tahu apa yang dilakukan XOR:
sumber
Ini mendapatkan XOR eksklusif logis untuk dua (atau lebih) variabel
Masalah pertama dengan pengaturan ini adalah bahwa kemungkinan besar melintasi seluruh daftar dua kali dan, setidaknya, akan memeriksa setidaknya satu dari elemen dua kali. Jadi mungkin meningkatkan pemahaman kode, tetapi tidak memberikan kecepatan (yang mungkin berbeda tergantung pada kasus penggunaan Anda).
Masalah kedua dengan pengaturan ini adalah memeriksa eksklusivitas terlepas dari jumlah variabel. Ini pada awalnya dapat dianggap sebagai fitur, tetapi masalah pertama menjadi jauh lebih signifikan karena jumlah variabel meningkat (jika mereka pernah melakukannya).
sumber
Xor
^
menggunakan Python. Ia mengembalikan:__xor__
.Jika Anda berniat menggunakannya pada string, memasukkannya ke dalam
bool
membuat operasi Anda tidak ambigu (bisa juga berartiset(str1) ^ set(str2)
).sumber
XOR diimplementasikan di
operator.xor
.sumber
Ini adalah bagaimana saya akan membuat tabel kebenaran apa pun. Untuk xor khususnya kami memiliki:
Lihat saja nilai-nilai T di kolom jawaban dan string bersama-sama semua kasus nyata dengan logis atau. Jadi, tabel kebenaran ini dapat diproduksi dalam kasus 2 atau 3. Oleh karena itu,
sumber
Kita dapat dengan mudah menemukan xor dari dua variabel dengan menggunakan:
Contoh:
sumber
xor("hey", "there")
>>> Benar, tapi bukan itu yang kita inginkan