Bagaimana Anda mendapatkan xor logis dari dua variabel dengan Python?

648

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'
Zach Hirsch
sumber
3
Bagaimana Anda mendefinisikan "xor" untuk beberapa string? Apa yang Anda rasa "abc" ^ "" harus mengembalikan yang tidak?
Mehrdad Afshari
18
Ini harus mengembalikan True, daripada membangkitkan pengecualian, karena hanya satu dari string yang Benar seperti yang didefinisikan oleh tipe bool Python normal.
Zach Hirsch
38
Saya kagum bahwa Python tidak memiliki operator infiks yang disebut "xor", yang akan menjadi implementasi Pythonic yang paling intuitif. Menggunakan "^" konsisten dengan bahasa lain, tetapi tidak terlalu mencolok seperti kebanyakan Python.
Mark E. Haase
13
@MehrdadAfshari Jawaban yang jelas untuk pertanyaan Anda adalah yang a xor adidefinisikan sebagai (a and not b) or (not a and b), dan karenanya a xor b, kapan adan bapakah karakter string, atau tipe lainnya, akan menghasilkan apa pun yang (a and not b) or (not a and b)dihasilkan.
Kaz
1
Masalahnya adalah dokumentasi itu buruk. ^ adalah "bitwise eksklusif atau", yang secara harfiah diartikan berarti sedikit demi sedikit, bukan bool demi bool. jadi x'FFFF00 '^ x'FFFF00' harus x'000000 '. Atau apakah ini hanya dimaksudkan untuk terjadi dengan char by char? dilemparkan sebagai angka? Kita perlu mengulang karakter string yang lebih pendek untuk mencocokkan panjang string yang lebih panjang. Semua ini harus dibangun.
mckenzm

Jawaban:

1188

Jika Anda sudah menormalkan input ke boolean, maka! = Adalah xor.

bool(a) != bool(b)
A. Coady
sumber
148
Meskipun ini pintar dan pendek, saya tidak yakin itu bersih. Ketika seseorang membaca konstruk ini dalam kode, apakah segera jelas bagi mereka bahwa ini adalah operasi xor? Saya merasa berkewajiban untuk menambahkan komentar - tanda bagi saya bahwa saya sedang menulis kode yang tidak jelas dan mencoba meminta maaf dengan komentar.
47
Mungkin "apakah ini jelas XOR?" adalah pertanyaan yang salah. Kami hanya mencoba melihat apakah jawaban untuk dua pertanyaan itu sama, dan berpikir kami akan menggunakan XOR untuk mengimplementasikannya. Misalnya, jika kita ingin memastikan bahwa kita tidak membandingkan apel dengan jeruk, apakah "jika xor (isApple (x), isApple (y))" benar-benar lebih jelas daripada "if isApple (x)! = IsApple (y)"? Bukan untuk ku!
AmigoNico
106
Ada masalah dengan menggunakan "! =" Sebagai xor. Anda mungkin berharap bool (a)! = Bool (b)! = Bool (c) sama dengan bool (a) ^ bool (b) ^ bool (c). Jadi jangan gips ke bool, tapi saya akan merekomendasikan ^. Untuk mengetahui apa yang terjadi pada contoh pertama lihat "operator chaining".
Elmo
19
@elmo: +1 untuk menunjukkan perbedaannya, dan +1 untuk mengajari saya apa itu chaining operator! Saya berada di kamp yang mengatakan bahwa! = Tidak dapat dibaca ^.
Mark E. Haase
13
bukankah seharusnya demikian bool(a) is not bool(b)?
RNA
485

Anda selalu dapat menggunakan definisi xor untuk menghitungnya dari operasi logis lainnya:

(a and not b) or (not a and b)

Tapi ini agak terlalu bertele-tele bagi saya, dan pada pandangan pertama tidak terlalu jelas. Cara lain untuk melakukannya adalah:

bool(a) ^ bool(b)

Operator xor pada dua boolean adalah xor logis (tidak seperti pada int, di mana bitwise). Yang masuk akal, karena boolhanya subkelas dariint , tetapi diimplementasikan untuk hanya memiliki nilai 0dan 1. Dan xor logis setara dengan xor bitwise ketika domain dibatasi untuk 0dan1 .

Jadi logical_xorfungsi akan diimplementasikan seperti:

def logical_xor(str1, str2):
    return bool(str1) ^ bool(str2)

Penghargaan untuk Nick Coghlan di milis Python-3000 .

Zach Hirsch
sumber
7
posting bagus, tetapi dari semua cara untuk memberi nama parameter Anda, mengapa 'str1' dan 'str2'?
SingleNegationElimination
1
@Token kenapa tidak. Apakah maksud Anda karena mereka tidak terlalu Pythonic?
orokusaki
1
@ Zach Hirsch Bisakah Anda menggunakan (bukan a dan b) alih-alih (b dan bukan a) untuk keterbacaan atau apakah definisi tersebut tidak sesuai dengan xor.
orokusaki
10
Anda harus meletakkan not pertama seperti ini (not b and a) or (not a and b)sehingga mengembalikan string jika ada, yang sepertinya cara pythonic untuk fungsi untuk beroperasi.
rjmunro
2
@TokenMacGuy: Apa yang Anda sarankan agar ia menamai mereka?
user541686
180

Bitwise eksklusif-atau sudah ada di dalam Python, dalam operatormodul (yang identik dengan ^operator):

from operator import xor
xor(bool(a), bool(b))  # Note: converting to bools is essential
penyanyi wanita
sumber
3
Inilah yang saya butuhkan. Ketika membalikkan malware rekayasa banyak kali string yang rusak sampai operasi XOR. Menggunakan chr ini (xor (ord ("n"), 0x1A)) = 't'
ril3y
75
Hati-hati, ini juga bitwise: xor(1, 2)pengembalian 3. Dari dokumentasi: xor(a, b) -- Same as a ^ b. Ingatlah bahwa apa pun yang diimpor dari operatorhanya bentuk fungsional dari operator infiks bawaan yang ada.
askewchan
5
@askewchan: boolJenis kelebihan __xor__untuk mengembalikan boolean. Ini akan bekerja dengan baik, tetapi berlebihan ketika bool(a) ^ bool(b)melakukan hal yang persis sama.
Martijn Pieters
@MartijnPieters ^Operator memanggil secara __xor__internal.
Quantum7
5
@ Quantum7: ya, saya tidak yakin mengapa Anda mengatakan ini padaku. Saya hanya mengatakan bahwa booltipe mengimplementasikan __xor__metode khusus karena ^menyebutnya . Intinya adalah bahwa bool(a) ^ bool(b)berfungsi dengan baik, tidak perlu menggunakan operator.xor()fungsi di sini.
Martijn Pieters
43

Seperti yang dijelaskan Zach , Anda dapat menggunakan:

xor = bool(a) ^ bool(b)

Secara pribadi, saya menyukai dialek yang sedikit berbeda:

xor = bool(a) + bool(b) == 1

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.

  • "1 = a ^ b ^ c ..." berarti jumlah operan benar ganjil. Operator ini "paritas".
  • "1 = a + b + c ..." berarti tepat satu operan benar. Ini "eksklusif atau", yang berarti "satu dengan mengesampingkan yang lain".
ddaa
sumber
12
Jadi, Benar + Benar + Salah + Benar == 3, dan 3! = 1, tetapi Benar XOR Benar XOR Salah XOR Benar == Benar. Bisakah Anda menguraikan "menerapkan XOR dengan benar di beberapa operan" dengan benar?
tzot
3
@tzot Contoh Anda gagal, karena menurut solusi ddaa, Anda menerapkan penambahan hanya pada dua variabel sekaligus. Jadi cara yang tepat untuk menuliskannya harus (((((True + True)==1)+False)==1)+True)==1. Jawaban yang diberikan di sini benar-benar digeneralisasikan ke beberapa operan.
ely
6
Juga, ada perbedaan antara XOR tiga arah vs. urutan dua operasi yang dikelompokkan dari dua XOR. Jadi 3-WAY-XOR (A, B, C) tidak sama dengan XOR (XOR (A, B), C). Dan contoh ddaa adalah yang pertama, sedangkan Anda mengasumsikan yang terakhir.
ely
3
@ Mr.F Penjelasan Anda tidak benar-benar memaafkan jawaban ini. Dalam Python, jika Anda hanya melakukan True + True + False + True, Anda jangan mendapatkan 3, dan True + True + False + True == 3memberikan kembali Truesementara True + True + False + True == 1memberikan kembali False. Dengan kata lain, jawabannya di sini tidak digeneralisasi dengan benar; untuk itu, Anda perlu melakukan pekerjaan tambahan. Sementara itu True ^ True ^ False ^ Truepekerjaan sederhana seperti yang diharapkan.
jpmc26
3
@ jpmc26 Saya tidak mengerti komentar Anda. Pendekatan tambahan dimaksudkan untuk menggeneralisasi operasi di mana Anda ingin memeriksa bahwa tepat satu operan True, XOR multi-arity. Ini adalah operasi yang berbeda dari, misalnya A XOR B XOR ... XOR Z,. Dengan kata lain, jika Anda berencana untuk menggunakan versi berbasis tambahan, maka setelah dikirimkan operan True + True + False + TrueAnda harus mengharapkan hasilnya Falsekarena lebih dari satu dari itu True, yang berfungsi jika kondisi memeriksa == 1.
ely
26
  • Python logis or: A or B: kembali Ajika bool(A)yaituTrue , jika tidak kembaliB
  • Python logis and:: A and Bmengembalikan Ajika bool(A)adaFalse , jika tidak kembaliB

Untuk menjaga sebagian besar cara berpikir itu, definisi logis saya adalah:

def logical_xor(a, b):
    if bool(a) == bool(b):
        return False
    else:
        return a or b

Dengan cara itu dapat kembali a, batau False:

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'
nosklo
sumber
5
Ini tampak buruk, atau paling tidak aneh, bagi saya. Tidak satu pun dari operator logis bawaan lainnya mengembalikan salah satu dari tiga nilai yang mungkin.
Zach Hirsch
2
@ Zach Hirsch: Itu sebabnya saya mengatakan "untuk mempertahankan sebagian besar cara berpikir" - karena tidak ada hasil yang baik ketika keduanya benar atau salah
nosklo
Operasi logis harus mengembalikan nilai logis, jadi "return a atau b" yang kedua terlihat aneh, jadi return kedua harus mengembalikan True.
Denis Barmenkov
9
@Denis Barmenkov: Yah, perhatikan bahwa operator logis python anddan ortidak akan mengembalikan nilai logis. 'foo' and 'bar'kembali 'bar'...
nosklo
6
Pada pandangan pertama, 2 jawaban sebelumnya sepertinya yang terbaik, tetapi setelah dipikir-pikir, yang ini sebenarnya satu-satunya yang benar, yaitu satu-satunya yang memberikan contoh xorimplementasi yang konsisten dengan built-in anddan or. Namun, tentu saja, dalam situasi praktis, bool(a) ^ bool(b)atau bahkan a ^ b(jika adan bdiketahui bool) tentu saja lebih ringkas.
Erik Kaplun
23

Saya telah menguji beberapa pendekatan dan not a != (not b)tampaknya menjadi yang tercepat.

Berikut ini beberapa tes

%timeit not a != (not b)
10000000 loops, best of 3: 78.5 ns per loop

%timeit bool(a) != bool(b)
1000000 loops, best of 3: 343 ns per loop

%timeit not a ^ (not b)
10000000 loops, best of 3: 131 ns per loop

Sunting: Contoh 1 dan 3 di atas tidak ada tanda kurung sehingga hasilnya salah. Hasil + truth()fungsi baru seperti yang disarankan ShadowRanger.

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns
Rugnar
sumber
6
Itu 100 ns dalam hidupku aku tidak akan kembali ;-)
Arel
4
Untuk penghitungan waktu antara, Anda dapat melakukannya from operator import truthdi bagian atas modul, dan menguji truth(a) != truth(b). boolmenjadi konstruktor memiliki banyak overhead yang tidak terhindarkan pada level C (harus menerima argumen yang setara *args, **kwargsdan menguraikan tupledan dictmengekstraknya), di mana truth(menjadi fungsi) dapat menggunakan jalur yang dioptimalkan yang tidak memerlukan salah satu tupleatau a dict, dan berjalan sekitar setengah dari waktu boolsolusi berbasis (tetapi masih lebih lama dari notsolusi berbasis).
ShadowRanger
9

Utas penghargaan:

Ide anoder ... Hanya Anda mencoba (mungkin) ekspresi pythonic «tidak» untuk mendapatkan perilaku logis «xor»

Tabel kebenarannya adalah:

>>> True is not True
False
>>> True is not False
True
>>> False is not True
True
>>> False is not False
False
>>>

Dan untuk string contoh Anda:

>>> "abc" is not  ""
True
>>> 'abc' is not 'abc' 
False
>>> 'abc' is not '' 
True
>>> '' is not 'abc' 
True
>>> '' is not '' 
False
>>> 

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.

Agustin Marcos
sumber
Saya juga biasa membacanya sebagai "sangat berbeda". Itu karena beberapa bahasa digunakan untuk mengimplementasikan operasi sedikit demi sedikit dari representasi biner dan mengambil bool dari operasi bitwise yang dihasilkan. Saya kira jawaban Anda lebih "anti peluru" karena melampaui ruang boolean.
Yucer
Maksud saya fakta bahwa jawaban Anda mencakup kasus membandingkan Tidak, Salah, '' karena berbeda adalah hal yang berbeda. Misalnya: bool (False)! = Bool ('') namun False tidak '' "lebih setuju dengan semantik" sangat berbeda "ini
yucer
8

Python memiliki operator eksklusif-ATAU bitwise, yaitu ^:

>>> True ^ False
True
>>> True ^ True
False
>>> False ^ True
True
>>> False ^ False
False

Anda dapat menggunakannya dengan mengonversi input ke boolean sebelum menerapkan xor ( ^):

bool(a) ^ bool(b)

(Diedit - terima kasih Arel)

Tomer Gal
sumber
Jawaban Anda harus menjelaskan bahwa itu ^adalah bitor xor (bukan xor logis seperti pertanyaan yang diajukan). bool(2) ^ bool(3)memberikan jawaban yang berbeda dari bool(2 ^ 3).
Arel
1
@Rel Tapi bukan itu masalahnya. a ^ badalah polimorf. Jika adan badalah boolcontoh, hasilnya juga akan boolbaik. Perilaku ini hampir tidak dapat disebut "bitwise" xor.
Alfe
@ Abfe poin penting adalah bahwa nilai harus dilemparkan ke boolean terlebih dahulu. Dokumentasi Python mendefinisikan ^sebagai bitwise, meskipun itu hal yang menarik yang jenis yang diawetkan untuk booldan intjenis. Catatan: True ^ 2adalah 3, menunjukkan bagaimana itu memang bitwise.
Arel
@Arel Ya, kasing bool ^ intini semacam memberikan segalanya untuk yang intpertama. Namun, Python telah built-in dengan ^operator yang selama bertahun-bit dalam intdan untuk satu bit diwakili dalam bool, sehingga keduanya bitwise , tetapi bitwise XOR untuk satu bit hanya adalah yang logis xor untuk boolean.
Alfe
Saya selalu benci menggunakan operator ini, meskipun saya memahaminya xor, berasal dari latar belakang teknik, bagi saya ini secara naluriah terasa seperti kekuatan matematika, yaitu 2^3 = pow(2,3)yang berarti saya selalu secara eksplisit berkomentar untuk mencegah kebingungan.
Nicholas Hamilton
8

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.

def xor(*vars):
    sum = False
    for v in vars:
        sum = sum ^ bool(v)
    return sum

Dan penggunaannya juga mudah:

if xor(False, False, True, False):
    print "Hello World!"

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:

def isOne(*vars):
    sum = False
    for v in vars:
        if sum and v:
            return False
        else:
            sum = sum or v
    return sum
mikha
sumber
Untuk meningkatkan jawaban ini: (bool(False) is False) == True. Anda bisa menggunakannya Falsepada baris tersebut.
pathunstrom
7

Eksklusif Atau didefinisikan sebagai berikut

def xor( a, b ):
    return (a or b) and not (a and b)
S.Lott
sumber
2
yang akan mengembalikan True untuk xor ('ini', '') dan untuk mengikuti cara python, ia harus mengembalikan 'ini'.
nosklo
@nosklo: Silakan dengan BDFL, tolong, bukan saya. Karena Python mengembalikan True, maka itu pasti cara Python.
S.Lott
2
Maksud saya untuk konsistensi dengan operator logis python lain - Python tidak mengembalikan Benar ketika saya melakukannya ('ini' atau ''), ia mengembalikan 'ini'. Tetapi dalam fungsi Anda xor ('this', '') mengembalikan True. Seharusnya mengembalikan 'ini' seperti yang dilakukan "atau" python builtin.
nosklo
10
Python anddan orlakukan hubungan arus pendek. Setiap xorpelaksanaan tidak bisa arus pendek, sehingga sudah ada ketidaksesuaian; oleh karena itu, tidak ada alasan yang xorharus beroperasi seperti and+ orlakukan.
tzot
7

Kadang-kadang saya menemukan diri saya bekerja dengan 1 dan 0 bukannya boolean nilai Benar dan Salah. Dalam hal ini xor dapat didefinisikan sebagai

z = (x + y) % 2

yang memiliki tabel kebenaran berikut:

     x
   |0|1|
  -+-+-+
  0|0|1|
y -+-+-+
  1|1|0|
  -+-+-+
Steve L.
sumber
7

Saya tahu ini terlambat, tetapi saya punya pemikiran dan mungkin layak, hanya untuk dokumentasi. Mungkin ini akan berhasil: np.abs(x-y)Idenya adalah itu

  1. jika x = Benar = 1 dan y = Salah = 0 maka hasilnya adalah | 1-0 | = 1 = Benar
  2. jika x = Salah = 0 dan y = Salah = 0 maka hasilnya adalah | 0-0 | = 0 = Salah
  3. jika x = Benar = 1 dan y = Benar = 1 maka hasilnya adalah | 1-1 | = 0 = Salah
  4. jika x = Salah = 0 dan y = Benar = 1 maka hasilnya adalah | 0-1 | = 1 = Benar
BarocliniCplusplus
sumber
7

Sederhana, mudah dimengerti:

sum( (bool(a), bool(b) ) == 1

Jika pilihan eksklusif adalah yang Anda cari, itu dapat diperluas ke beberapa argumen:

sum( bool(x) for x in y ) % 2 == 1
cz
sumber
1
sum(map(bool, y)) % 2 == 1
warvariuc
6

Bagaimana dengan ini?

(not b and a) or (not a and b)

akan memberi ajika bsalah
akan memberi bjika asalah
akan memberi Falsesebaliknya

Atau dengan ekspresi terner Python 2.5+:

(False if a else b) if b else a
Markus Jarderot
sumber
6

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, xorimplementasi yang mengembalikan salah satu Trueatau Falsecukup 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, harus xor(None, -1, [], True)kembali None, []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.

def xor(*operands, falsechoice = -2, truechoice = -2):
  """A single-evaluation, multi-operand, full-choice xor implementation
  falsechoice, truechoice: 0 = always bool, +/-1 = first/last operand, +/-2 = first/last match"""
  if not operands:
    raise TypeError('at least one operand expected')
  choices = [falsechoice, truechoice]
  matches = {}
  result = False
  first = True
  value = choice = None
  # avoid using index or slice since operands may be an infinite iterator
  for operand in operands:
    # evaluate each operand once only so as to avoid unintended side effects
    value = bool(operand)
    # the actual xor operation
    result ^= value
    # choice for the current operand, which may or may not match end result
    choice = choices[value]
    # if choice is last match;
    # or last operand and the current operand, in case it is last, matches result;
    # or first operand and the current operand is indeed first;
    # or first match and there hasn't been a match so far
    if choice < -1 or (choice == -1 and value == result) or (choice == 1 and first) or (choice > 1 and value not in matches):
      # store the current operand
      matches[value] = operand
    # next operand will no longer be first
    first = False
  # if choice for result is last operand, but they mismatch
  if (choices[result] == -1) and (result != value):
    return result
  else:
    # return the stored matching operand, if existing, else result as bool
    return matches.get(result, result)

testcases = [
  (-1, None, True, {None: None}, [], 'a'),
  (None, -1, {None: None}, 'a', []),
  (None, -1, True, {None: None}, 'a', []),
  (-1, None, {None: None}, [], 'a')]
choices = {-2: 'last match', -1: 'last operand', 0: 'always bool', 1: 'first operand', 2: 'first match'}
for c in testcases:
  print(c)
  for f in sorted(choices.keys()):
    for t in sorted(choices.keys()):
      x = xor(*c, falsechoice = f, truechoice = t)
      print('f: %d (%s)\tt: %d (%s)\tx: %s' % (f, choices[f], t, choices[t], x))
  print()

sumber
5

Banyak orang, termasuk saya, membutuhkan xorfungsi 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.

def xor(*args):
   """
   This function accepts an arbitrary number of input arguments, returning True
   if and only if bool() evaluates to True for an odd number of the input arguments.
   """

   return bool(sum(map(bool,args)) % 2)

Contoh I / O berikut:

In [1]: xor(False, True)
Out[1]: True

In [2]: xor(True, True)
Out[2]: False

In [3]: xor(True, True, True)
Out[3]: True
Phillip M. Feldman
sumber
5

Untuk mendapatkan xor logis dari dua atau lebih variabel dalam Python:

  1. Konversikan input ke boolean
  2. Gunakan bitwise xor operator ( ^atau operator.xor)

Sebagai contoh,

bool(a) ^ bool(b)

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 !=:

True ^  False ^  False  # True, as expected of XOR
True != False != False  # False! Equivalent to `(True != False) and (False != False)`

(PS Saya mencoba mengedit jawaban yang diterima untuk memasukkan peringatan ini, tetapi perubahan saya ditolak.)

Arel
sumber
4

Sangat mudah ketika Anda tahu apa yang dilakukan XOR:

def logical_xor(a, b):
    return (a and not b) or (not a and b)

test_data = [
  [False, False],
  [False, True],
  [True, False],
  [True, True],
]

for a, b in test_data:
    print '%r xor %s = %r' % (a, b, logical_xor(a, b))
Denis Barmenkov
sumber
4

Ini mendapatkan XOR eksklusif logis untuk dua (atau lebih) variabel

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")

any([str1, str2]) and not all([str1, str2])

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

Marc
sumber
4

Xor ^menggunakan Python. Ia mengembalikan:

  • Bitor xor untuk int
  • Logor logis untuk bools
  • Serikat eksklusif untuk set
  • Hasil yang ditentukan pengguna untuk kelas yang mengimplementasikan __xor__ .
  • TypeError untuk tipe yang tidak ditentukan, seperti string atau kamus.

Jika Anda berniat menggunakannya pada string, memasukkannya ke dalam boolmembuat operasi Anda tidak ambigu (bisa juga berarti set(str1) ^ set(str2)).

Arthur Havlicek
sumber
3

XOR diimplementasikan di operator.xor.

lbolla
sumber
8
operator.xor sesuai dengan operasi bitwise, yang merupakan salah satu yang tidak diinginkan oleh pengirim aslinya.
Niriel
@ Kojiro ternyata begitu!
Arel
3

Ini adalah bagaimana saya akan membuat tabel kebenaran apa pun. Untuk xor khususnya kami memiliki:

| a | b  | xor   |             |
|---|----|-------|-------------|
| T | T  | F     |             |
| T | F  | T     | a and not b |
| F | T  | T     | not a and b |
| F | F  | F     |             |

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,

xor = lambda a, b: (a and not b) or (not a and b)
snagpaul
sumber
-6

Kita dapat dengan mudah menemukan xor dari dua variabel dengan menggunakan:

def xor(a,b):
    return a !=b

Contoh:

xor (Benar, Salah) >>> Benar

Muhammad Abdullah
sumber
1
atau xor("hey", "there")>>> Benar, tapi bukan itu yang kita inginkan
Mayou36