¿Cómo se obtiene el xor lógico? de dos variables en Python?
Por ejemplo, tengo dos variables que espero sean cadenas. Quiero probar que solo uno de ellos contiene un valor Verdadero (no es Ninguno o la cadena vacía):
str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
print "bad"
El ^
operador parece ser bit a bit y no está definido en todos los 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
fuente
fuente
a xor a
se define como(a and not b) or (not a and b)
y, por lo tantoa xor b
, cuándoa
yb
son cadenas de caracteres, o cualquier otro tipo, deberían producir cualquier(a and not b) or (not a and b)
rendimiento.Respuestas:
Si ya está normalizando las entradas a booleanos, entonces! = Es xor.
fuente
bool(a) is not bool(b)
en su lugar?Siempre puede usar la definición de xor para calcularla a partir de otras operaciones lógicas:
Pero esto es demasiado detallado para mí, y no es particularmente claro a primera vista. Otra forma de hacerlo es:
El operador xor en dos booleanos es xor lógico (a diferencia de los ints, donde es bit a bit). Lo cual tiene sentido, ya que
bool
es solo una subclase deint
, pero se implementa para tener solo los valores0
y1
. Y xor lógico es equivalente a xor bit a bit cuando el dominio está restringido a0
y1
.Entonces la
logical_xor
función se implementaría como:Crédito a Nick Coghlan en la lista de correo Python-3000 .
fuente
(not b and a) or (not a and b)
manera para que devuelva la cadena si hubiera una, que parece ser la forma pitónica para que funcione la función.Bitwise exclusive-or ya está integrado en Python, en el
operator
módulo (que es idéntico al^
operador):fuente
xor(1, 2)
retornos3
. Desde la cadena de documentación:xor(a, b) -- Same as a ^ b.
recuerde que cualquier cosa importadaoperator
es solo una forma funcional de un operador infijo incorporado existente.bool
tipo se sobrecarga__xor__
para devolver booleanos. Funcionará bien, pero es excesivo cuandobool(a) ^ bool(b)
hace exactamente lo mismo.^
operador llama__xor__
internamente.bool
tipo implementa el__xor__
método específicamente porque lo^
llama . El punto es quebool(a) ^ bool(b)
funciona bien, no hay necesidad de usar laoperator.xor()
función aquí.Como explicó Zach , puedes usar:
Personalmente, estoy a favor de un dialecto ligeramente diferente:
Este dialecto está inspirado en un lenguaje de diagramación lógico que aprendí en la escuela, donde "OR" se denota con un cuadro que contiene
≥1
(mayor o igual que 1) y "XOR" se denota con un cuadro que contiene=1
.Esto tiene la ventaja de implementar correctamente operandos exclusivos o múltiples.
fuente
(((((True + True)==1)+False)==1)+True)==1
. La respuesta dada aquí se generaliza totalmente a múltiples operandos.True + True + False + True
, que no consigue3
, yTrue + True + False + True == 3
le da la espaldaTrue
, mientras queTrue + True + False + True == 1
da vueltaFalse
. En otras palabras, la respuesta aquí no se generaliza correctamente; para que lo haga, debe hacer un trabajo adicional. Mientras tanto, un simpleTrue ^ True ^ False ^ True
funciona como se esperaba.True
, un XOR de aria múltiple. Esta es una operación diferente a, por ejemploA XOR B XOR ... XOR Z
,. En otras palabras, si planea usar la versión basada en la adición, luego de enviar los operandosTrue + True + False + True
, debe esperar que el resultado seaFalse
más de unoTrue
, lo que funciona si la condición lo comprueba== 1
.or
::A or B
devuelveA
sibool(A)
esTrue
, de lo contrario devuelveB
and
::A and B
devuelveA
sibool(A)
esFalse
, de lo contrario devuelveB
Para mantener la mayor parte de esa forma de pensar, mi definición lógica o xor sería:
De esa manera se puede devolver
a
,b
oFalse
:fuente
and
yor
no devolverán el valor lógico.'foo' and 'bar'
vuelve'bar'
...xor
implementación que es coherente con el incorporadoand
yor
. Sin embargo, por supuesto, en situaciones prácticas,bool(a) ^ bool(b)
o inclusoa ^ b
(sia
yb
son conocidos por serbool
) son más concisa, por supuesto.He probado varios enfoques y
not a != (not b)
parecía ser el más rápido.Aquí hay algunas pruebas
Editar: los ejemplos 1 y 3 anteriores faltan paréntesis, por lo que el resultado es incorrecto. Nuevos resultados +
truth()
función como sugirió ShadowRanger.fuente
from operator import truth
en la parte superior del módulo y probartruth(a) != truth(b)
.bool
ser un constructor tiene una sobrecarga inevitable en el nivel C (debe aceptar argumentos como el equivalente*args, **kwargs
y analizartuple
ydict
extraerlos), dondetruth
(siendo una función) puede usar una ruta optimizada que no requiere untuple
o adict
, y se ejecuta en aproximadamente la mitad del tiempo de lasbool
soluciones basadas (pero aún más tiempo que lasnot
soluciones basadas).Hilo gratificante:
Una idea más antigua ... Solo intente la (puede ser) expresión pitónica «no es» para obtener un comportamiento de «xor» lógico
La tabla de verdad sería:
Y para su cadena de ejemplo:
Sin embargo; como indicaron anteriormente, depende del comportamiento real que desee extraer de cualquier par de cuerdas, porque las cuerdas no son boletines ... y aún más: si se «sumerge en Python» encontrará «La naturaleza peculiar de" y "y" o "» http://www.diveintopython.net/power_of_introspection/and_or.html
Lo siento, mi inglés escrito, no es mi lengua materna.
Saludos.
fuente
Python tiene un operador OR exclusivo bit a bit, es
^
:Puede usarlo convirtiendo las entradas a booleanos antes de aplicar xor (
^
):(Editado - gracias Arel)
fuente
^
es un xor bit a bit (no xor lógico como la pregunta formulada).bool(2) ^ bool(3)
da una respuesta diferente quebool(2 ^ 3)
.a ^ b
es polimorfo Sia
yb
sonbool
instancias, el resultado también lo serábool
. Este comportamiento difícilmente se puede llamar un xor "bit a bit".^
como bit a bit, aunque es un punto interesante para el que se conservan los tiposbool
y losint
tipos. Nota:True ^ 2
es3
, demostrando cómo es de hecho bit a bit.bool ^ int
caso es poner todo enint
primer lugar. Aún así, Python ha incorporado el^
operador para muchos bitsint
y para el bit representado en abool
, por lo que ambos son bit a bit , pero el bit xor para un solo bit es el xor lógico para booleanos.xor
, desde una formación en ingeniería, para mí esto instintivamente se siente como un poder matemático, es2^3 = pow(2,3)
decir, que siempre comento explícitamente para evitar confusiones.Como no veo la variante simple de xor usando argumentos variables y solo operando con valores de Verdad Verdadero o Falso, lo lanzaré aquí para que cualquiera lo use. Es como lo han señalado otros, bastante (por no decir muy) directo.
Y el uso también es sencillo:
Como este es el XOR lógico n-ario generalizado, su valor de verdad será verdadero siempre que el número de operandos verdaderos sea impar (y no solo cuando exactamente uno es verdadero, este es solo un caso en el que XOR n-ario es verdadero).
Por lo tanto, si está buscando un predicado n-ario que solo sea verdadero cuando exactamente uno de sus operandos lo es, es posible que desee usar:
fuente
(bool(False) is False) == True
. Simplemente puede usarFalse
en esas líneas.Exclusivo O se define de la siguiente manera
fuente
and
yor
hacer cortocircuito. Cualquierxor
implementación no puede provocar un cortocircuito, por lo que ya existe una discrepancia; por lo tanto, no hay razón para quexor
funcione comoand
+or
do.A veces me encuentro trabajando con 1 y 0 en lugar de valores booleanos True y False. En este caso, xor se puede definir como
que tiene la siguiente tabla de verdad:
fuente
Sé que es tarde, pero pensé y podría valer la pena, solo por documentación. Quizás esto funcionaría:
np.abs(x-y)
la idea es quefuente
Simple, fácil de entender:
Si lo que busca es una opción exclusiva, puede expandirse a múltiples argumentos:
fuente
sum(map(bool, y)) % 2 == 1
¿Qué tal esto?
dará
a
sib
es falsodará
b
sia
es falsodará
False
contrarioO con la expresión ternaria Python 2.5+:
fuente
Algunas de las implementaciones sugeridas aquí causarán una evaluación repetida de los operandos en algunos casos, lo que puede provocar efectos secundarios no deseados y, por lo tanto, debe evitarse.
Dicho esto, una
xor
implementación que devuelveTrue
oFalse
es bastante simple; uno que devuelve uno de los operandos, si es posible, es mucho más complicado, porque no existe consenso sobre qué operando debe ser el elegido, especialmente cuando hay más de dos operandos. Por ejemplo, deberíaxor(None, -1, [], True)
regresarNone
,[]
oFalse
? Apuesto a que cada respuesta parece ser la más intuitiva para algunas personas.Para el resultado Verdadero o Falso, hay hasta cinco opciones posibles: devolver el primer operando (si coincide con el resultado final en valor, de lo contrario booleano), devolver la primera coincidencia (si existe al menos uno, de lo contrario booleano), devolver el último operando (si ... más ...), devolver la última coincidencia (si ... más ...), o siempre devolver boolean. En total, eso es 5 ** 2 = 25 sabores de
xor
.fuente
Mucha gente, incluido yo mismo, necesita una
xor
función que se comporte como un circuito xor de entrada n, donde n es variable. (Ver https://en.wikipedia.org/wiki/XOR_gate ). La siguiente función simple implementa esto.Muestra de E / S a continuación:
fuente
Para obtener el xor lógico de dos o más variables en Python:
^
ooperator.xor
)Por ejemplo,
Cuando convierte las entradas a booleanos, xor bit a bit se convierte en xor lógico .
Tenga en cuenta que la respuesta aceptada es incorrecta:
!=
no es lo mismo que xor en Python debido a la sutileza del encadenamiento del operador .Por ejemplo, el xor de los tres valores siguientes es incorrecto cuando se usa
!=
:(PD: intenté editar la respuesta aceptada para incluir esta advertencia, pero mi cambio fue rechazado).
fuente
Es fácil cuando sabes lo que hace XOR:
fuente
Esto obtiene el XOR lógico exclusivo para dos (o más) variables
El primer problema con esta configuración es que lo más probable es que atraviese la lista completa dos veces y, como mínimo, verifique dos veces al menos uno de los elementos. Por lo tanto, puede aumentar la comprensión del código, pero no se presta a la velocidad (que puede diferir insignificantemente según su caso de uso).
El segundo problema con esta configuración es que verifica la exclusividad independientemente del número de variables. Al principio, esto puede considerarse como una característica, pero el primer problema se vuelve mucho más significativo a medida que aumenta el número de variables (si alguna vez lo hacen).
fuente
Xor está
^
en Python. Vuelve :__xor__
.Si tiene la intención de usarlos en cadenas de todos modos, al transmitirlos,
bool
su operación no es ambigua (también podría significarset(str1) ^ set(str2)
).fuente
XOR se implementa en
operator.xor
.fuente
Así es como codificaría cualquier tabla de verdad. Para xor en particular tenemos:
Basta con mirar los valores T en la columna de respuesta y unir todos los casos verdaderos con lógico o. Entonces, esta tabla de verdad se puede producir en el caso 2 o 3. Por lo tanto,
fuente
Podemos encontrar fácilmente xor de dos variables usando:
Ejemplo:
fuente
xor("hey", "there")
>>> Es cierto, pero eso no es lo que queremos