Como você obtém o xor lógico de duas variáveis no Python?
Por exemplo, eu tenho duas variáveis que eu espero que sejam strings. Quero testar se apenas um deles contém um valor True (não é None ou a string vazia):
str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
print "bad"
O ^
operador parece estar bit a bit e não definido em todos os objetos:
>>> 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
fonte
fonte
a xor a
é definida como(a and not b) or (not a and b)
e, portantoa xor b
, quandoa
eb
são cadeias de caracteres, ou quaisquer outros tipos, devem render os(a and not b) or (not a and b)
rendimentos.Respostas:
Se você já está normalizando as entradas para booleanos, então! = É xor.
fonte
bool(a) is not bool(b)
?Você sempre pode usar a definição de xor para computá-la de outras operações lógicas:
Mas isso é um pouco detalhado demais para mim e não é particularmente claro à primeira vista. Outra maneira de fazer isso é:
O operador xor em dois booleanos é xor lógico (ao contrário de ints, onde é bit a bit). O que faz sentido, já que
bool
é apenas uma subclasse deint
, mas é implementado para ter apenas os valores0
e1
. E xor lógico é equivalente a xor bit a bit quando o domínio está restrito a0
e1
.Portanto, a
logical_xor
função seria implementada como:Agradecemos a Nick Coghlan na lista de correspondência do Python-3000 .
fonte
(not b and a) or (not a and b)
para que ele retorne a string, se houver, que parece ser a maneira pitônica da função funcionar.Bitwise exclusivo - ou já está embutido no Python, no
operator
módulo (que é idêntico ao^
operador):fonte
xor(1, 2)
retorna3
. Na documentação:xor(a, b) -- Same as a ^ b.
Lembre - se de que qualquer coisa importadaoperator
é apenas uma forma funcional de um operador de infixo interno existente.bool
tipo sobrecarrega__xor__
para retornar booleanos. Vai funcionar muito bem, mas é um exagero quandobool(a) ^ bool(b)
faz exatamente a mesma coisa.^
operador chama__xor__
internamente.bool
tipo implementa o__xor__
método especificamente porque o^
chama . O ponto é quebool(a) ^ bool(b)
funciona bem, não há necessidade de usar aoperator.xor()
função aqui.Como Zach explicou, você pode usar:
Pessoalmente, sou a favor de um dialeto ligeiramente diferente:
Esse dialeto é inspirado em uma linguagem de diagramação lógica que aprendi na escola, em que "OR" era indicado por uma caixa contendo
≥1
(maior ou igual a 1) e "XOR" era indicado por uma caixa contendo=1
.Isso tem a vantagem de implementar corretamente operandos exclusivos ou em múltiplos.
fonte
(((((True + True)==1)+False)==1)+True)==1
. A resposta dada aqui generaliza totalmente para múltiplos operandos.True + True + False + True
, você não conseguir3
, eTrue + True + False + True == 3
dá para trásTrue
enquantoTrue + True + False + True == 1
dá de voltaFalse
. Em outras palavras, a resposta aqui não generaliza corretamente; para isso, você precisa fazer um trabalho adicional. Enquanto isso, um simplesTrue ^ True ^ False ^ True
funciona como esperado.True
um XOR de várias regiões. Esta é uma operação diferente da, por exemploA XOR B XOR ... XOR Z
,. Em outras palavras, se você planeja usar a versão baseada em adição, ao enviar os operandos,True + True + False + True
você deve esperar que o resultado sejaFalse
uma vez que mais de um deles éTrue
, o que funciona se a condição verificar== 1
.or
::A or B
retornaA
sebool(A)
forTrue
, caso contrário, retornaB
and
::A and B
retornaA
sebool(A)
forFalse
, caso contrário, retornaB
Para manter a maior parte desse modo de pensar, minha definição lógica de xor seria:
Dessa forma, ele pode retornar
a
,b
ouFalse
:fonte
and
eor
não retornarão valor lógico.'foo' and 'bar'
retorna'bar'
...xor
implementação que é consistente com o built-inand
eor
. No entanto, é claro, em situações práticas,bool(a) ^ bool(b)
ou mesmoa ^ b
(sea
eb
são conhecidos por serembool
) são mais conciso, claro.Eu testei várias abordagens e
not a != (not b)
parecia ser o mais rápido.Aqui estão alguns testes
Edit: Os exemplos 1 e 3 acima estão faltando parênteses, portanto o resultado está incorreto. Novos resultados +
truth()
funcionam como sugerido pelo ShadowRanger.fonte
from operator import truth
na parte superior do módulo e testartruth(a) != truth(b)
.bool
ser um construtor tem muita sobrecarga inevitável no nível C (ele deve aceitar argumentos como o equivalente*args, **kwargs
e analisartuple
edict
extraí-los), ondetruth
(sendo uma função) pode usar um caminho otimizado que não exijatuple
ou adict
e é executado em cerca de metade do tempo dasbool
soluções baseadas (mas ainda mais do que asnot
soluções baseadas).Segmento de recompensa:
Idéia de ânodo ... Basta tentar a expressão pitônica (pode ser) «não é» para obter o comportamento lógico «xor»
A tabela verdade seria:
E para o seu exemplo de string:
Contudo; como indicado acima, depende do comportamento real que você deseja obter sobre algumas cordas, porque cordas não são boleanas ... e ainda mais: se você «Dive Into Python», encontrará «The Peculiar Nature of" e "and" ou "» http://www.diveintopython.net/power_of_introspection/and_or.html
Desculpe meu inglês escrito, não é minha língua nativa.
Saudações.
fonte
Python tem um operador OR exclusivo bit a bit, é
^
:Você pode usá-lo convertendo as entradas em booleanos antes de aplicar xor (
^
):(Editado - obrigado Arel)
fonte
^
é um xor bit a bit (não é lógico como a pergunta).bool(2) ^ bool(3)
dá uma resposta diferente debool(2 ^ 3)
.a ^ b
é polimorfo. Sea
eb
sãobool
instâncias, o resultado também serábool
. Esse comportamento dificilmente pode ser chamado de xor "bit a bit".^
como bit a bit, mesmo que seja um ponto interessante para o qual os tipos são preservadosbool
e osint
tipos. Nota:True ^ 2
é3
, demonstrando como é de fato bit a bit.bool ^ int
caso é meio que lançar tudoint
primeiro. Ainda assim, o Python incorporou o^
operador para muitos bits noint
e para o bit representado em umbool
, então ambos são bit a bit , mas o xor bit a bit para um único bit é apenas o xor lógico para os booleanos.xor
, vindo de uma experiência em engenharia, isso me parece instintivamente um poder matemático, ou seja, o2^3 = pow(2,3)
que significa que eu sempre comento explicitamente para evitar confusão.Como não vejo a variante simples do xor usando argumentos variáveis e apenas a operação nos valores de Verdadeiro Verdadeiro ou Falso, vou jogá-lo aqui para qualquer um usar. É como observado por outros, bastante (para não dizer muito) direto.
E o uso também é direto:
Como esse é o XOR lógico n-ário generalizado, seu valor de verdade será True sempre que o número de operandos True for ímpar (e não apenas quando exatamente um for True, este é apenas um caso em que o XOR n-ário é True).
Portanto, se você estiver em busca de um predicado n-ário que seja apenas True quando exatamente um de seus operandos for, convém usar:
fonte
(bool(False) is False) == True
. Você pode apenas usarFalse
nessas linhas.Exclusive Or é definido da seguinte forma
fonte
and
eor
fazer curto-circuito. Qualquerxor
implementação não pode causar um curto-circuito; portanto, já existe uma discrepância; portanto, não há razãoxor
para operar comoand
+or
do.Às vezes me pego trabalhando com 1 e 0 em vez de valores booleanos True e False. Nesse caso, xor pode ser definido como
que possui a seguinte tabela de verdade:
fonte
Sei que é tarde, mas pensei em algo que poderia valer a pena, apenas para documentação. Talvez isso funcione:
np.abs(x-y)
a idéia é quefonte
Simples, fácil de entender:
Se você deseja uma opção exclusiva, ela pode ser expandida para vários argumentos:
fonte
sum(map(bool, y)) % 2 == 1
Que tal agora?
dará
a
seb
for falsodará
b
sea
for falsodará
False
caso contrárioOu com a expressão ternária do Python 2.5+:
fonte
Algumas das implementações sugeridas aqui causarão repetidas avaliações dos operandos em alguns casos, o que pode levar a efeitos colaterais indesejados e, portanto, deve ser evitado.
Dito isto, uma
xor
implementação que retorna umaTrue
ouFalse
é bastante simples; aquele que retorna um dos operandos, se possível, é muito mais complicado, porque não existe consenso sobre qual operando deve ser o escolhido, especialmente quando há mais de dois operandos. Por exemplo, devexor(None, -1, [], True)
retornarNone
,[]
ouFalse
? Aposto que cada resposta aparece para algumas pessoas como a mais intuitiva.Para o resultado Verdadeiro ou Falso, existem até cinco opções possíveis: retornar primeiro operando (se corresponder ao resultado final em valor, senão booleano), retornar primeiro resultado (se houver pelo menos um, senão booleano), return last operand (if ... else ...), return last match (if ... else ...), ou sempre retorne booleano. No total, são 5 ** 2 = 25 sabores de
xor
.fonte
Muitas pessoas, inclusive eu, precisam de uma
xor
função que se comporte como um circuito xor de entrada n, onde n é variável. (Consulte https://en.wikipedia.org/wiki/XOR_gate ). A seguinte função simples implementa isso.E / S de amostra a seguir:
fonte
Para obter o xor lógico de duas ou mais variáveis no Python:
^
ouoperator.xor
)Por exemplo,
Quando você converte as entradas em booleanos, xor bit a bit se torna xor lógico .
Observe que a resposta aceita está errada:
!=
não é a mesma que xor no Python devido à sutileza do encadeamento do operador .Por exemplo, o xor dos três valores abaixo está errado ao usar
!=
:(PS: tentei editar a resposta aceita para incluir esse aviso, mas minha alteração foi rejeitada.)
fonte
É fácil quando você sabe o que o XOR faz:
fonte
Isso obtém o XOR exclusivo lógico para duas (ou mais) variáveis
O primeiro problema dessa configuração é que ela provavelmente percorre a lista inteira duas vezes e, no mínimo, verifica pelo menos um dos elementos duas vezes. Portanto, isso pode aumentar a compreensão do código, mas não leva à velocidade (que pode diferir de maneira insignificante dependendo do seu caso de uso).
O segundo problema com essa instalação é que ele verifica a exclusividade, independentemente do número de variáveis. Isso pode ser visto a princípio como um recurso, mas o primeiro problema se torna muito mais significativo à medida que o número de variáveis aumenta (se é que o fazem).
fonte
Xor está
^
em Python. Retorna:__xor__
.Se você pretende usá-los em cadeias de qualquer maneira, convertê-las em
bool
torna sua operação inequívoca (você também pode querer dizerset(str1) ^ set(str2)
).fonte
O XOR é implementado no
operator.xor
.fonte
É assim que eu codificaria qualquer tabela de verdade. Para o xor em particular, temos:
Basta olhar para os valores T na coluna de resposta e juntar todos os casos verdadeiros com lógica ou. Portanto, essa tabela de verdade pode ser produzida nos casos 2 ou 3. Portanto,
fonte
Podemos encontrar facilmente xor de duas variáveis usando:
Exemplo:
fonte
xor("hey", "there")
>>> Verdade, mas não é isso que queremos #