Как вы получаете логический xor двух переменных в Python?

Я согласен с предыдущими ответами, но хочу сказать, что:

if ( K == 1 ) 
{ 
   C = 0
   M = 0
   Y = 0
} 

Это может быть, если r = g = b = 0.

555
задан rushi 24 August 2018 в 13:20
поделиться

9 ответов

Если Вы уже нормализуете исходные данные к булевским переменным, то! = xor.

bool(a) != bool(b)
1076
ответ дан A. Coady 24 August 2018 в 23:20
поделиться

Как насчет этого?

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

даст a, если b будет ложен
, то даст b, если a будет ложен
, то даст False иначе

Или с Python 2.5 + троичное выражение:

(False if a else b) if b else a
6
ответ дан Markus Jarderot 24 August 2018 в 23:20
поделиться
  • 1
    Хорошо. I' ll идут для проверки его. Спасибо. I' m собирающийся сказать Вас позже, если это работает на меня:) – imarban 22 June 2013 в 04:43

Эксклюзивный Или определяется следующим образом

def xor( a, b ):
    return (a or b) and not (a and b)
7
ответ дан S.Lott 24 August 2018 в 23:20
поделиться
  • Python, логичный or: A or B: возвраты A, если bool(A) True, иначе возвращаются B
  • Python, логичный and: A and B: возвраты A, если bool(A) False, иначе возвращаются B

Для хранения большей части того образа мыслей, мой логический xor definintion был бы:

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

Тот путь это может возвратиться a, b, или False:

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'
23
ответ дан nosklo 24 August 2018 в 23:20
поделиться
  • 1
    @nilskp, там какая-либо документация, которая говорит, почему track by должен быть в конце? I' m задающийся вопросом, кроме почему track by позволяют где-либо еще в конце, если он вызывает нежелательное поведение. – adam0101 16 May 2014 в 08:58

Можно всегда использовать определение xor для вычислений его из других логических операций:

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

, Но это является немного слишком подробным для меня и не является особенно ясным на первый взгляд. Другой способ сделать это:

bool(a) ^ bool(b)

оператор XOR на двух булевских переменных является логическим xor (в отличие от этого, на ints, где это является поразрядным). Который имеет смысл, так как bool просто подкласс int , но реализован, чтобы только иметь значения 0 и 1. И логический xor эквивалентен поразрядному xor, когда домен ограничивается 0 и 1.

Так эти logical_xor функция была бы реализована как:

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

Кредит к [1 111] Nick Coghlan в списке рассылки Python 3000 .

438
ответ дан Zach Hirsch 24 August 2018 в 23:20
поделиться

Как объясненный Zach, можно использовать:

xor = bool(a) ^ bool(b)

Лично, я одобряю немного отличающийся диалект:

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

Этот диалект вдохновлен логическим языком схематического изображения, который я выучил в школе, где "ИЛИ" был обозначен полем, содержащим ≥1 (больше, чем или равный 1), и "XOR" был обозначен полем, содержащим =1.

Это имеет преимущество корректной реализации эксклюзивного или на нескольких операндах.

  • "1 = ^ b ^ c..." означает, что количество истинных операндов нечетно. Этот оператор является "четностью".
  • "1 = + b + c..." означает точно, что один операнд верен. Это "эксклюзивно или", означая "один исключая другие".
38
ответ дан Community 24 August 2018 в 23:20
поделиться
  • 1
    @nilskp просто спас мою жизнь с тем комментарием. +999 – willoller 24 May 2014 в 06:16

Получить логический xor двух или больше переменных в Python:

  1. Преобразовывают исходные данные в булевские переменные
  2. Использование поразрядный оператор XOR (^ или operator.xor)

, Например,

bool(a) ^ bool(b)

, Когда Вы преобразовываете исходные данные в булевские переменные, поразрядный , xor становится логичным xor.

Примечание, что принятый ответ является неправильным: != не то же как xor в Python из-за тонкости оператор, объединяющий в цепочку .

, Например, xor трех значений ниже является неправильным при использовании !=:

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

(P.S. Я пытался редактировать принятый ответ для включения этого предупреждения, но мое изменение было отклонено.)

4
ответ дан 22 November 2019 в 22:02
поделиться

Some of the implementations suggested here will cause repeated evaluation of the operands in some cases, which may lead to unintended side effects and therefore must be avoided.

That said, a xor implementation that returns either True or False is fairly simple; one that returns one of the operands, if possible, is much trickier, because no consensus exists as to which operand should be the chosen one, especially when there are more than two operands. For instance, should xor(None, -1, [], True) return None, [] or False? I bet each answer appears to some people as the most intuitive one.

For either the True- or the False-result, there are as many as five possible choices: return first operand (if it matches end result in value, else boolean), return first match (if at least one exists, else boolean), return last operand (if ... else ...), return last match (if ... else ...), or always return boolean. Altogether, that's 5 ** 2 = 25 flavors of 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()
6
ответ дан 22 November 2019 в 22:02
поделиться

Поскольку я не вижу простого варианта xor с использованием переменных аргументов и только операции со значениями истины True или False, я просто добавлю его сюда для кому угодно. Как отметили другие, довольно (чтобы не сказать очень) просто.

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

И использование также простое:

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

Так как это обобщенный n-арный логический XOR, его истинное значение будет True, если число истинных операндов нечетное (а не только когда истинно один из них, это только один случай, когда n-арное XOR истинно).

Таким образом, если вы ищете n-арный предикат, который истинен только тогда, когда равен ровно один из его операндов, вы можете использовать:

def isOne(*vars):
    sum = False
    for v in vars:
        if sum and v:
            return False
        else:
            sum = sum or v
    return sum
7
ответ дан 22 November 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: