Làm thế nào để bạn có được xor logic của hai biến trong Python?


648

Làm thế nào để bạn có được xor logic của hai biến trong Python?

Ví dụ, tôi có hai biến mà tôi mong đợi là chuỗi. Tôi muốn kiểm tra rằng chỉ một trong số chúng chứa giá trị True (không phải là Không hoặc chuỗi trống):

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
    print "ok"
else:
    print "bad"

Các ^nhà điều hành có vẻ là Bitwise, và không xác định trên tất cả các đối tượng:

>>> 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'

3
Làm thế nào để bạn xác định "xor" cho một vài chuỗi? Bạn cảm thấy "abc" ^ "" nên trả lại cái gì không?
Mehrdad Afshari

18
Nó sẽ trả về True, thay vì đưa ra một ngoại lệ, vì chỉ một trong các chuỗi là True như được định nghĩa bởi loại bool của Python bình thường.
Zach Hirsch

38
Tôi ngạc nhiên khi Python không có toán tử infix gọi là "xor", đây sẽ là cách triển khai Pythonic trực quan nhất. Sử dụng "^" phù hợp với các ngôn ngữ khác, nhưng không dễ đọc như hầu hết Python.
Đánh dấu E. Haase

13
@MehrdadAfshari Câu trả lời rõ ràng cho câu hỏi của bạn là a xor ađược định nghĩa là (a and not b) or (not a and b), và do đó a xor b, khi ablà các chuỗi ký tự, hoặc bất kỳ loại nào khác, sẽ mang lại bất kỳ kết quả nào (a and not b) or (not a and b).
Kaz

1
Vấn đề là tài liệu kém. ^ là "bitwise độc ​​quyền hoặc", theo nghĩa đen có nghĩa là từng bit, không phải bool by bool. vì vậy x'FFFF00 '^ x'FFFF00' nên là x'000000 '. Hoặc điều này chỉ có nghĩa là xảy ra trên một char bởi cơ sở char? đúc như số? Chúng ta cần lặp lại các ký tự chuỗi ngắn hơn để phù hợp với độ dài của chuỗi dài hơn. Tất cả điều này nên được xây dựng trong.
mckenzm 22/03/2015

Câu trả lời:


1188

Nếu bạn đã bình thường hóa đầu vào thành booleans, thì! = Là xor.

bool(a) != bool(b)

148
Mặc dù điều này là thông minh và ngắn gọn, tôi không tin nó sạch sẽ. Khi ai đó đọc cấu trúc này trong mã, có phải ngay lập tức rõ ràng với họ rằng đây là một hoạt động xor? Tôi cảm thấy bắt buộc phải thêm một bình luận - một dấu hiệu cho tôi rằng tôi đang viết mã không rõ ràng và cố gắng xin lỗi bằng một bình luận.

47
Có lẽ "rõ ràng đó là XOR?" là câu hỏi sai Chúng tôi chỉ cố gắng xem liệu câu trả lời cho hai câu hỏi có giống nhau không, và nghĩ rằng chúng tôi sẽ sử dụng XOR để thực hiện điều đó. Ví dụ: nếu chúng tôi muốn đảm bảo rằng chúng tôi không so sánh táo với cam, thì "if xor (isApple (x), isApple (y))" thực sự rõ ràng hơn "if isApple (x)! = IsApple (y)"? Không phải với tôi!
AmigoNico

106
Có vấn đề với việc sử dụng "! =" Làm xor. Bạn có thể mong đợi bool (a)! = Bool (b)! = Bool (c) giống với bool (a) ^ bool (b) ^ bool (c). Vì vậy, làm phôi để bool, nhưng tôi muốn giới thiệu ^. Để biết những gì đang diễn ra trong ví dụ đầu tiên, hãy tìm kiếm "chuỗi vận hành".
elmo

19
@elmo: +1 để chỉ ra sự khác biệt và +1 để dạy cho tôi biết chuỗi vận hành là gì! Tôi ở trong trại nói rằng! = Không thể đọc được như ^.
Đánh dấu E. Haase

13
nó nên được bool(a) is not bool(b)thay thế?
RNA

485

Bạn luôn có thể sử dụng định nghĩa của xor để tính toán nó từ các hoạt động logic khác:

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

Nhưng điều này hơi quá dài dòng đối với tôi và không đặc biệt rõ ràng ngay từ cái nhìn đầu tiên. Một cách khác để làm điều đó là:

bool(a) ^ bool(b)

Toán tử xor trên hai booleans là xor logic (không giống như trên ints, trong đó bitwise). Điều này có nghĩa, vì boolchỉ là một lớp con củaint , nhưng được triển khai để chỉ có các giá trị 01. Và xor logic tương đương với xwise bitwise khi miền bị giới hạn 01.

Vì vậy, logical_xorchức năng sẽ được thực hiện như sau:

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

Tín dụng cho Nick Coghlan trong danh sách gửi thư Python-3000 .


7
bài đăng tuyệt vời, nhưng trong tất cả các cách để đặt tên cho các tham số của bạn, tại sao 'str1' và 'str2'?
SingleNegationElimination

1
@Token tại sao không. Ý bạn là bởi vì họ không phải là Pythonic?
orokusaki

1
@Zach Hirsch Bạn có thể sử dụng (không phải a và b) thay vì (b và không phải a) để dễ đọc hoặc định nghĩa sẽ không phù hợp với xor.
orokusaki

10
Bạn nên đặt các thông báo đầu tiên như thế này (not b and a) or (not a and b)để nó trả về chuỗi nếu có một chuỗi, có vẻ như là cách pythonic cho chức năng hoạt động.
rjmunro

2
@TokenMacGuy: Bạn đã gợi ý anh ấy nên đặt tên cho chúng là gì?
dùng541686

180

Bitwise độc quyền - hoặc đã được tích hợp sẵn trong Python, trong operatormô-đun (giống hệt với ^toán tử):

from operator import xor
xor(bool(a), bool(b))  # Note: converting to bools is essential

3
Đây là những gì tôi cần. Khi phần mềm độc hại kỹ thuật đảo ngược rất nhiều lần chuỗi được xử lý cho đến khi hoạt động XOR. Sử dụng chr này (xor (ord ("n"), 0x1A)) = 't'
ril3y

75
Hãy cẩn thận, đây cũng là bitwise: xor(1, 2)trả về 3. Từ chuỗi doc: xor(a, b) -- Same as a ^ b. Hãy nhớ rằng mọi thứ được nhập từ operatorchỉ là một dạng chức năng của toán tử infix dựng sẵn.
askewchan

5
@askewchan: boolKiểu quá tải __xor__để trả về booleans. Nó sẽ hoạt động tốt, nhưng nó quá mức khi bool(a) ^ bool(b)thực hiện chính xác điều tương tự.
Martijn Pieters

@MartijnPieters Nhà ^điều hành gọi __xor__nội bộ.
Quantum7

5
@ Quantum7: vâng, tôi không chắc tại sao bạn lại nói với tôi điều này. Tôi chỉ nói rằng boolkiểu này thực hiện __xor__phương thức cụ thể vì ^gọi nó . Điểm đang bool(a) ^ bool(b)hoạt động tốt, không cần sử dụng operator.xor()chức năng ở đây.
Martijn Pieters

43

Như Zach đã giải thích, bạn có thể sử dụng:

xor = bool(a) ^ bool(b)

Cá nhân, tôi ủng hộ một phương ngữ hơi khác:

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

Phương ngữ này được lấy cảm hứng từ một ngôn ngữ lập biểu đồ logic mà tôi đã học ở trường nơi "HOẶC" được biểu thị bằng một hộp chứa ≥1(lớn hơn hoặc bằng 1) và "XOR" được biểu thị bằng một hộp chứa =1.

Điều này có lợi thế của việc thực hiện chính xác độc quyền hoặc trên nhiều toán hạng.

  • "1 = a ^ b ^ c ..." có nghĩa là số toán hạng thực là số lẻ. Toán tử này là "chẵn lẻ".
  • "1 = a + b + c ..." có nghĩa chính xác một toán hạng là đúng. Đây là "độc quyền hoặc", có nghĩa là "một loại trừ những cái khác".

12
Vì vậy, True + True + false + True == 3 và 3! = 1, nhưng True XOR True XOR Sai XOR True == True. Bạn có thể giải thích "thực hiện chính xác XOR trên nhiều toán hạng" không?
tzot

3
@tzot Ví dụ của bạn không thành công, vì theo giải pháp của ddaa, bạn chỉ áp dụng bổ sung trên hai biến số một lần. Vì vậy, cách đúng để viết tất cả sẽ phải là (((((True + True)==1)+False)==1)+True)==1. Câu trả lời được đưa ra ở đây hoàn toàn khái quát cho nhiều toán hạng.
ely

6
Ngoài ra, có một sự khác biệt giữa một bộ XOR ba chiều so với bộ XOR được nhóm theo thứ tự hoạt động. Vì vậy, 3-CÁCH-XOR (A, B, C) không giống với XOR (XOR (A, B), C). Và ví dụ của ddaa là cái trước, trong khi cái của bạn giả định cái sau.
ely

3
@ Mr.F Giải thích của bạn không thực sự tha cho câu trả lời này. Trong Python, nếu bạn chỉ cần làm True + True + False + True, bạn sẽ nhận được 3True + True + False + True == 3trả lại Truetrong khi True + True + False + True == 1trả lại False. Nói cách khác, câu trả lời ở đây không khái quát chính xác; để làm như vậy, bạn cần phải làm thêm. Trong khi đó một True ^ True ^ False ^ Truecông việc đơn giản như mong đợi.
jpmc26

3
@ jpmc26 Tôi không hiểu bình luận của bạn. Cách tiếp cận bổ sung có nghĩa là để khái quát hóa hoạt động mà bạn muốn kiểm tra chính xác một toán hạng đó là TrueXOR đa năng. Đây là một hoạt động khác với, ví dụ , A XOR B XOR ... XOR Z. Nói cách khác, nếu bạn có kế hoạch sử dụng phiên bản dựa trên bổ sung, thì sau khi gửi các toán hạng trong True + True + False + Truebạn, bạn sẽ mong đợi kết quả sẽ có Falsenhiều hơn một trong số đó True, hoạt động nếu điều kiện kiểm tra == 1.
ely

26
  • Python logic or:: A or Btrả về Anếu bool(A)True, nếu không thì trả vềB
  • Python logic and:: A and Btrả về Anếu bool(A)False, nếu không thì trả vềB

Để giữ phần lớn lối suy nghĩ đó, định nghĩa xor logic của tôi sẽ là:

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

Bằng cách đó nó có thể quay trở lại a, bhoặc False:

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'

5
Điều này có vẻ xấu, hoặc ít nhất là kỳ lạ, với tôi. Không có toán tử logic tích hợp nào khác trả về một trong ba giá trị có thể.
Zach Hirsch

2
@Zach Hirsch: Đó là lý do tại sao tôi nói "giữ phần lớn lối suy nghĩ đó" - vì không có kết quả tốt khi cả hai đều đúng hoặc sai
nosklo

Hoạt động logic phải trả về giá trị logic, do đó, "return a hoặc b" thứ hai trông lạ, vì vậy trả về thứ hai phải trả về True.
Denis Barmenkov

9
@Denis Barmenkov: Chà, lưu ý rằng các toán tử logic python andorsẽ không trả về giá trị logic. 'foo' and 'bar'trả lại 'bar'...
nosklo

6
Thoạt nhìn, 2 câu trả lời trước có vẻ như là tốt nhất, nhưng theo suy nghĩ thứ hai, câu trả lời này thực sự là câu trả lời đúng duy nhất, tức là câu trả lời duy nhất cung cấp một ví dụ về cách xortriển khai phù hợp với tích hợp andor. Tuy nhiên, tất nhiên, trong các tình huống thực tế, bool(a) ^ bool(b)hoặc thậm chí a ^ b(nếu abđược biết là bool) tất nhiên ngắn gọn hơn.
Erik Kaplun

23

Tôi đã thử nghiệm một số cách tiếp cận và not a != (not b)dường như là nhanh nhất.

Dưới đây là một số bài kiểm tra

%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

Chỉnh sửa: Ví dụ 1 và 3 ở trên thiếu dấu ngoặc đơn nên kết quả không chính xác. Kết quả mới + truth()chức năng như ShadowRanger đề xuất.

%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

6
Đó là 100 ns của cuộc đời tôi, tôi sẽ không quay lại ;-)
Arel 25/07/19

4
Đối với thời gian ở giữa, bạn có thể thực hiện from operator import truthở đầu mô-đun và kiểm tra truth(a) != truth(b). boollà một nhà xây dựng có rất nhiều chi phí không thể tránh khỏi ở cấp độ C (nó phải chấp nhận các đối số tương đương *args, **kwargsvà phân tích tupledicttrích xuất chúng), trong đó truth(là một hàm) có thể sử dụng một đường dẫn tối ưu hóa không yêu cầu một tuplehoặc a dict, và chạy trong khoảng một nửa thời gian của các boolgiải pháp dựa trên (nhưng vẫn dài hơn notcác giải pháp dựa trên).
ShadowRanger

9

Phần thưởng:

Ý tưởng về bộ giải mã ... Chỉ cần bạn thử biểu thức pythonic (có thể) «không» để có được hành vi logic «xor»

Bảng sự thật sẽ là:

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

Và cho chuỗi ví dụ của bạn:

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

Tuy nhiên; như họ đã chỉ ra ở trên, nó phụ thuộc vào hành vi thực tế mà bạn muốn rút ra về bất kỳ chuỗi nào, bởi vì chuỗi không phải là ... và thậm chí hơn thế nữa: nếu bạn «Đi sâu vào Python», bạn sẽ tìm thấy «Bản chất đặc biệt của" và "và" hoặc "» http://www.diveintopython.net/power_of_introspection/and_or.html

Xin lỗi tiếng Anh viết của tôi, nó không phải là ngôn ngữ sinh ra của tôi.

Trân trọng.


Tôi cũng sử dụng để đọc nó là "hoàn toàn khác nhau". Đó là bởi vì một số ngôn ngữ sử dụng để thực hiện từng chút một của biểu diễn nhị phân và lấy bool của hoạt động bitwise kết quả. Tôi đoán câu trả lời của bạn là "chống đạn" hơn bởi vì nó vượt ra ngoài không gian boolean.
yucer

Ý tôi là thực tế là câu trả lời của bạn bao gồm trường hợp so sánh Không, Sai, 'vì khác biệt là những thứ đặc biệt. Ví dụ: bool (Sai)! = Bool ('') tuy nhiên Sai không phải là '' "đồng ý nhiều hơn với ngữ nghĩa của" khác biệt nghiêm ngặt "
yucer 28/03/19

8

Python có toán tử OR độc quyền bitwise, đó là ^:

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

Bạn có thể sử dụng nó bằng cách chuyển đổi các đầu vào thành booleans trước khi áp dụng xor ( ^):

bool(a) ^ bool(b)

(Đã chỉnh sửa - cảm ơn Arel)


Câu trả lời của bạn nên làm rõ rằng đó ^là một xor bitwise (không phải là xor logic như câu hỏi được hỏi). bool(2) ^ bool(3)đưa ra một câu trả lời khác hơn bool(2 ^ 3).
Arel

1
@Arel Nhưng đó không phải là trường hợp. a ^ blà đa hình. Nếu abbooltrường hợp, kết quả cũng sẽ boolnhư vậy. Hành vi này khó có thể được gọi là xor "bitwise".
Alfe

@ Alfe điểm quan trọng là các giá trị phải được chuyển thành booleans trước. Tài liệu Python định nghĩa ^theo bitwise, mặc dù đó là một điểm thú vị mà các kiểu được bảo tồn boolintcác kiểu. Lưu ý: True ^ 23, chứng minh làm thế nào nó thực sự là bitwise.
Arel

@Arel Vâng, bool ^ inttrường hợp này là loại đúc mọi thứ intđầu tiên. Tuy nhiên, Python đã được xây dựng trong các ^nhà điều hành cho nhiều bit trong intvà cho một bit đại diện trong một bool, vì vậy cả hai đều Bitwise , nhưng Bitwise xor cho một chút đơn chỉ sự logic xor cho các phép toán luận.
Alfe

Tôi luôn ghét sử dụng toán tử này, mặc dù tôi hiểu nó xor, xuất phát từ nền tảng kỹ thuật, với tôi cảm giác này theo bản năng giống như một năng lực toán học, nghĩa 2^3 = pow(2,3)là tôi luôn bình luận rõ ràng để tránh nhầm lẫn.
Nicholas Hamilton

8

Vì tôi không thấy biến thể đơn giản của xor khi sử dụng các đối số biến và chỉ hoạt động trên các giá trị Truth Đúng hoặc Sai, tôi sẽ chỉ ném nó ở đây cho bất kỳ ai sử dụng. Nó được ghi nhận bởi những người khác, khá đơn giản (không phải nói rất nhiều).

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

Và việc sử dụng cũng đơn giản:

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

Vì đây là XOR logic n-ary tổng quát, nên giá trị thật của nó sẽ là True bất cứ khi nào số toán hạng True là số lẻ (và không chỉ khi chính xác một là True, đây chỉ là một trường hợp trong đó XOR của n-ary là True).

Do đó, nếu bạn đang tìm kiếm một vị từ n-ary chỉ đúng khi chính xác một trong các toán hạng của nó, bạn có thể muốn sử dụng:

def isOne(*vars):
    sum = False
    for v in vars:
        if sum and v:
            return False
        else:
            sum = sum or v
    return sum

Để cải thiện câu trả lời này : (bool(False) is False) == True. Bạn chỉ có thể sử dụng Falsetrên những dòng.
pathunstrom

7

Độc quyền Hoặc được định nghĩa như sau

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

2
sẽ trả về True cho xor ('this', '') và theo cách của python, nó sẽ trả về 'this'.
nosklo

@nosklo: Làm ơn mang nó lên với BDFL, làm ơn, không phải tôi. Vì Python trả về True, nên đó phải là cách của Python.
S.Lott

2
Ý tôi là sự nhất quán với các toán tử logic python khác - Python không trả về True khi tôi làm ('this' hoặc ''), nó trả về 'this'. Nhưng trong hàm xor của bạn ('this', '') trả về True. Nó sẽ trả về 'cái này' như "hoặc" python dựng sẵn.
nosklo

10
Python andorlàm ngắn mạch. Bất kỳ xorthực hiện nào cũng không thể đoản mạch, do đó đã có sự khác biệt; do đó, không có lý do nào xornên hoạt động như and+ orlàm.
tzot

7

Đôi khi tôi thấy mình làm việc với 1 và 0 thay vì giá trị boolean Đúng và Sai. Trong trường hợp này xor có thể được định nghĩa là

z = (x + y) % 2

trong đó có bảng chân lý sau:

     x
   |0|1|
  -+-+-+
  0|0|1|
y -+-+-+
  1|1|0|
  -+-+-+

7

Tôi biết điều này là muộn, nhưng tôi đã có một suy nghĩ và nó có thể có giá trị, chỉ để làm tài liệu. Có lẽ điều này sẽ làm việc: np.abs(x-y)Ý tưởng là

  1. nếu x = True = 1 và y = false = 0 thì kết quả sẽ là | 1-0 | = 1 = True
  2. nếu x = Sai = 0 và y = Sai = 0 thì kết quả sẽ là | 0-0 | = 0 = Sai
  3. nếu x = True = 1 và y = True = 1 thì kết quả sẽ là | 1-1 | = 0 = Sai
  4. if x = false = 0 và y = True = 1 thì kết quả sẽ là | 0-1 | = 1 = True

7

Đơn giản, dễ hiểu:

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

Nếu một lựa chọn độc quyền là những gì bạn theo đuổi, nó có thể được mở rộng thành nhiều đối số:

sum( bool(x) for x in y ) % 2 == 1

1
sum(map(bool, y)) % 2 == 1
warvariuc

6

Còn cái này thì sao?

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

sẽ cho anếu blà sai
sẽ cho bnếu alà sai
sẽ cho Falsekhác

Hoặc với biểu thức ternary Python 2.5+:

(False if a else b) if b else a

6

Một số triển khai được đề xuất ở đây sẽ gây ra sự đánh giá lặp lại của các toán hạng trong một số trường hợp, điều này có thể dẫn đến các tác dụng phụ ngoài ý muốn và do đó phải tránh.

Điều đó nói rằng, xorviệc thực hiện trả về một trong hai Truehoặc Falsekhá đơn giản; một cái trả về một trong các toán hạng, nếu có thể, sẽ phức tạp hơn nhiều, bởi vì không có sự đồng thuận nào tồn tại như toán hạng nào nên được chọn, đặc biệt là khi có nhiều hơn hai toán hạng. Chẳng hạn, nên xor(None, -1, [], True)trả lại None, []hay False? Tôi đặt cược mỗi câu trả lời xuất hiện cho một số người là câu trả lời trực quan nhất.

Đối với kết quả Đúng hoặc Kết quả sai, có tối đa năm lựa chọn có thể: trả về toán hạng đầu tiên (nếu nó khớp với kết quả cuối cùng về giá trị, khác boolean), trả về kết quả khớp đầu tiên (nếu có ít nhất một tồn tại, khác boolean), trả về toán hạng cuối cùng (nếu ... khác ...), trả về kết quả cuối cùng (nếu ... khác ...) hoặc luôn trả về boolean. Nhìn chung, đó là 5 ** 2 = 25 hương vị của 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()

5

Nhiều người, bao gồm cả bản thân tôi, cần một xorchức năng hoạt động như một mạch xor đầu vào n, trong đó n là biến. (Xem https://en.wikipedia.org/wiki/XOR_gate ). Các chức năng đơn giản sau đây thực hiện điều này.

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)

Mẫu I / O sau:

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

5

Để có được xor logic của hai hoặc nhiều biến trong Python:

  1. Chuyển đổi đầu vào thành booleans
  2. Sử dụng toán tử xor bitwise ( ^hoặc operator.xor)

Ví dụ,

bool(a) ^ bool(b)

Khi bạn chuyển đổi các đầu vào thành booleans, bitwise xor trở thành xor logic .

Lưu ý rằng câu trả lời được chấp nhận là sai: != không giống như xor trong Python vì sự tinh tế của chuỗi toán tử .

Chẳng hạn, xor của ba giá trị dưới đây là sai khi sử dụng !=:

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

(PS Tôi đã thử chỉnh sửa câu trả lời được chấp nhận để đưa vào cảnh báo này, nhưng thay đổi của tôi đã bị từ chối.)


4

Thật dễ dàng khi bạn biết XOR làm gì:

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

4

Điều này nhận được XOR độc quyền logic cho hai (hoặc nhiều) biến

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

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

Vấn đề đầu tiên với thiết lập này là rất có thể nó đi qua toàn bộ danh sách hai lần và, ở mức tối thiểu, sẽ kiểm tra ít nhất một trong các yếu tố hai lần. Vì vậy, nó có thể tăng khả năng hiểu mã, nhưng nó không cho vay tốc độ (có thể khác nhau tùy theo trường hợp sử dụng của bạn).

Vấn đề thứ hai với thiết lập này là nó kiểm tra tính độc quyền bất kể số lượng biến. Điều này ban đầu có thể được coi là một tính năng, nhưng vấn đề đầu tiên trở nên quan trọng hơn rất nhiều khi số lượng biến tăng (nếu chúng từng làm).


4

Xor là ^trong Python. Nó trở lại :

  • Một xor bitwise cho ints
  • Xor logic cho bools
  • Một liên minh độc quyền cho các bộ
  • Kết quả do người dùng định nghĩa cho các lớp thực hiện __xor__.
  • TypeError cho các loại không xác định, chẳng hạn như chuỗi hoặc từ điển.

Nếu bạn có ý định sử dụng chúng trên các chuỗi bằng mọi cách, việc đưa chúng vào boollàm cho hoạt động của bạn không rõ ràng (bạn cũng có thể có nghĩa set(str1) ^ set(str2)).



3

Đây là cách tôi sẽ mã hóa bất kỳ bảng sự thật. Đối với xor nói riêng, chúng tôi có:

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

Chỉ cần nhìn vào các giá trị T trong cột trả lời và xâu chuỗi tất cả các trường hợp đúng với logic hoặc. Vì vậy, bảng chân lý này có thể được sản xuất trong trường hợp 2 hoặc 3. Do đó,

xor = lambda a, b: (a and not b) or (not a and b)

-6

Chúng ta có thể dễ dàng tìm thấy xor của hai biến bằng cách sử dụng:

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

Thí dụ:

xor (Đúng, Sai) >>> Đúng


1
hoặc xor("hey", "there")>>> Đúng, nhưng đó không phải là điều chúng ta muốn
Mayou36
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.