Как вы получаете логический xor двух переменных в Python?
Например, у меня есть две переменные, которые я ожидаю, чтобы быть строками. Я хочу проверить, что только один из них содержит значение True (не None или пустую строку):
str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
print "bad"
^
Оператор , кажется, побитовое и не определены на всех объектах:
>>> 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
Зак Хирш
источник
источник
a xor a
он определен как(a and not b) or (not a and b)
, и поэтомуa xor b
, когдаa
иb
являются символьными строками, или любыми другими типами, они должны давать любые результаты(a and not b) or (not a and b)
.Ответы:
Если вы уже нормализуете входные данные для логических значений, тогда! = Is xor.
источник
bool(a) is not bool(b)
вместо этого?Вы всегда можете использовать определение xor для вычисления его из других логических операций:
Но для меня это слишком многословно и на первый взгляд не совсем понятно. Еще один способ сделать это:
Оператор xor на двух логических значениях является логическим xor (в отличие от целых, где он побитовый). Что имеет смысл, так как
bool
это просто подклассint
, но реализован так, чтобы иметь только значения0
и1
. И логический xor эквивалентен побитовому xor, когда домен ограничен0
и1
.Таким образом,
logical_xor
функция будет реализована так:Благодарим Ника Коглана из списка рассылки Python-3000 .
источник
(not b and a) or (not a and b)
так, чтобы он возвращал строку, если она была, что похоже на питонный способ работы функции.Побитовое исключение или уже встроено в Python в
operator
модуле (который идентичен^
оператору):источник
xor(1, 2)
возвращает3
. Из строки документации:xor(a, b) -- Same as a ^ b.
Помните, что все, что импортируется из,operator
является просто функциональной формой существующего встроенного инфиксного оператора.bool
тип перегружается__xor__
для возврата логических значений. Это будет работать просто отлично, но это излишне, когдаbool(a) ^ bool(b)
делает то же самое.^
Оператор вызывает__xor__
внутри страны.bool
тип реализует__xor__
метод именно потому, что^
вызывает его . Дело в том, что этоbool(a) ^ bool(b)
работает нормально, здесь нет необходимости использоватьoperator.xor()
функцию.Как объяснил Зак , вы можете использовать:
Лично я предпочитаю немного другой диалект
Этот диалект навеян языком логических диаграмм, который я выучил в школе, где «ИЛИ» обозначалось полем, содержащим
≥1
(больше или равным 1), а «XOR» обозначалось полем, содержащим=1
.Это имеет преимущество правильной реализации исключительного или нескольких операндов.
источник
(((((True + True)==1)+False)==1)+True)==1
. Ответ, данный здесь, полностью обобщает несколько операндов.True + True + False + True
, вы действительно получите3
, иTrue + True + False + True == 3
возвращает вTrue
то времяTrue + True + False + True == 1
отдаетFalse
. Другими словами, ответ здесь не обобщается правильно; для этого вам нужно проделать дополнительную работу. Между тем простаяTrue ^ True ^ False ^ True
работа, как и ожидалось.True
многофакторным XOR. Это другая операция, чем, напримерA XOR B XOR ... XOR Z
,. Другими словами, если вы планируете использовать версию, основанную на сложении, то после отправки операндов вTrue + True + False + True
вас следует ожидать, что результат будетFalse
более одногоTrue
, который работает, если условие проверяется== 1
.or
:A or B
возвращает,A
еслиbool(A)
естьTrue
, иначе возвращаетB
and
:A and B
возвращает,A
еслиbool(A)
естьFalse
, иначе возвращаетB
Чтобы сохранить большую часть этого мышления, мое логическое определение xor будет:
Таким образом , он может вернуться
a
,b
илиFalse
:источник
and
иor
не будет возвращать логическое значение.'foo' and 'bar'
возвращается'bar'
...xor
реализации, согласующейся со встроеннымand
иor
. Однако, конечно, в практических ситуациях,bool(a) ^ bool(b)
или дажеa ^ b
(еслиa
иb
как известно, будутbool
), конечно, более кратким.Я протестировал несколько подходов и
not a != (not b)
оказался самым быстрым.Вот несколько тестов
Изменить: в примерах 1 и 3 выше отсутствуют круглые скобки, поэтому результат неверен. Новые результаты +
truth()
функция, как предложил ShadowRanger.источник
from operator import truth
в верхней части модуля и проверитьtruth(a) != truth(b)
.bool
будучи конструктор имеет много неизбежных накладных расходов на уровне C (он должен принимать аргументы в качестве эквивалента*args, **kwargs
и разбораtuple
иdict
извлечь их), гдеtruth
(будучи функцией) можно использовать оптимизированный путь , который не требует либоtuple
или аdict
, и работает в около половины времениbool
решений , основанных (но все еще больше , чемnot
решения на основе).Награждение темы:
Идея анодера ... Просто попробуйте (возможно) питонское выражение «нет», чтобы получить логическое поведение «xor»
Таблица истинности будет:
И для вашего примера строка:
Однако; как они указали выше, это зависит от фактического поведения, которое вы хотите извлечь из любой пары строк, потому что строки не являются логическими значениями ... и даже более того: если вы «Dive Into Python», вы найдете «The Pegetarian Nature» и «и» или «» http://www.diveintopython.net/power_of_introspection/and_or.html
Извините за мой английский, это не мой родной язык.
С уважением.
источник
В Python есть побитовый оператор исключающего ИЛИ, это
^
:Вы можете использовать его, преобразовав входные данные в логические значения перед применением xor (
^
):(Отредактировано - спасибо Арель)
источник
^
это битовый xor (не логический xor, как заданный вопрос).bool(2) ^ bool(3)
дает другой ответ, чемbool(2 ^ 3)
.a ^ b
это полиморф. Еслиa
иb
естьbool
экземпляры, результат будетbool
также. Такое поведение вряд ли можно назвать «побитовым» xor.^
как побитовую, хотя это интересный момент, для которого типыbool
иint
типы сохраняются . Примечание:True ^ 2
есть3
, демонстрируя, насколько оно действительно побитовое.bool ^ int
дело вроде как все ставит наint
первое место. Тем не менее, Python имеет встроенный в^
операторе для многих битint
и для одного бита представлены вbool
, так как это побитовое , но побитовом исключающем для одного бита просто является логическим исключающей для булевыми.xor
, исходя из инженерного опыта, для меня это инстинктивно ощущается как математическая сила, то есть,2^3 = pow(2,3)
что означает, что я всегда явно комментирую, чтобы избежать путаницы.Поскольку я не вижу простого варианта xor, использующего переменные аргументы и только операции со значениями True, True или False, я просто брошу его здесь для любого использования. Это, как отмечают другие, довольно (если не сказать очень) просто.
И использование также просто:
Так как это обобщенный n-арный логический XOR, его значение истины будет True, когда число операндов True нечетно (и не только когда точно один равен True, это всего лишь один случай, когда n-арный XOR равен True).
Таким образом, если вы ищете n-арный предикат, который имеет значение True только тогда, когда есть только один из его операндов, вы можете использовать:
источник
(bool(False) is False) == True
. Вы можете просто использоватьFalse
на этих линиях.Исключительно или определяется следующим образом
источник
and
иor
сделать короткое замыкание. Любаяxor
реализация не может замкнуть накоротко, поэтому уже есть несоответствие; следовательно, нет причины, котораяxor
должна работать какand
+or
do.Иногда я работаю с 1 и 0 вместо логических значений True и False. В этом случае xor может быть определен как
который имеет следующую таблицу истинности:
источник
Я знаю, что уже поздно, но у меня была мысль, и это может стоить, просто для документации. Возможно, это сработает:
np.abs(x-y)
идея в том, чтоисточник
Просто, легко понять:
Если вам нужен эксклюзивный выбор, его можно расширить до нескольких аргументов:
источник
sum(map(bool, y)) % 2 == 1
Как насчет этого?
даст
a
еслиb
ложьдаст
b
еслиa
ложьдаст
False
иначеИли с троичным выражением Python 2.5+:
источник
Некоторые из предложенных здесь реализаций будут вызывать повторную оценку операндов в некоторых случаях, что может привести к непреднамеренным побочным эффектам и, следовательно, их следует избегать.
Это сказано,
xor
реализация , которая возвращает либоTrue
илиFalse
достаточно просто; тот, который возвращает один из операндов, если это возможно, гораздо хитрее, потому что не существует единого мнения относительно того, какой операнд должен быть выбранным, особенно когда имеется более двух операндов. Например, долженxor(None, -1, [], True)
вернутьсяNone
,[]
илиFalse
? Могу поспорить, что каждый ответ кажется некоторым людям наиболее интуитивным.Для True- или False-результата есть пять возможных вариантов: вернуть первый операнд (если он соответствует конечному результату по значению, иначе логическое значение), вернуть первое совпадение (если хотя бы один существует, иначе логическое значение), вернуть последний операнд (если ... еще ...), вернуть последнее совпадение (если ... еще ...) или всегда вернуть логическое значение. В целом, это 5 ** 2 = 25 вкусов
xor
.источник
Многим людям, включая меня, нужна
xor
функция, которая ведет себя как схема x-n-входа, где n - переменная. (См. Https://en.wikipedia.org/wiki/XOR_gate ). Следующая простая функция реализует это.Пример ввода / вывода:
источник
Чтобы получить логический xor двух или более переменных в Python:
^
илиoperator.xor
)Например,
Когда вы конвертируете входные данные в логические значения, битовый xor становится логическим xor.
Обратите внимание, что принятый ответ неверен:
!=
это не то же самое, что xor в Python из-за тонкости объединения операторов .Например, xor из трех значений ниже является неправильным при использовании
!=
:(PS Я попытался отредактировать принятый ответ, чтобы включить это предупреждение, но мое изменение было отклонено.)
источник
Это легко, когда вы знаете, что делает XOR:
источник
Это получает логический эксклюзивный XOR для двух (или более) переменных
Первая проблема с этой настройкой заключается в том, что она, скорее всего, дважды пересекает весь список и, как минимум, дважды проверит хотя бы один из элементов. Таким образом, это может улучшить понимание кода, но не увеличивает скорость (которая может незначительно отличаться в зависимости от вашего варианта использования).
Вторая проблема с этой настройкой заключается в том, что она проверяет исключительность независимо от количества переменных. Это может поначалу рассматриваться как особенность, но первая проблема становится намного более значимой по мере увеличения числа переменных (если они когда-либо будут).
источник
Xor
^
в Python. Возвращает:__xor__
.Если вы все равно намереваетесь использовать их для строк, приведение к ним
bool
делает вашу работу однозначной (вы также можете это иметь в видуset(str1) ^ set(str2)
).источник
XOR реализован в
operator.xor
.источник
Вот как я бы кодировал любую таблицу истинности. В частности, для xor имеем:
Просто посмотрите на значения T в столбце ответов и объедините все истинные случаи с логическим или. Таким образом, эта таблица истинности может быть получена в случае 2 или 3. Следовательно,
источник
Мы можем легко найти xor двух переменных, используя:
Пример:
источник
xor("hey", "there")
>>> Правда, но это не то, что мы хотим