¿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 ase define como(a and not b) or (not a and b)y, por lo tantoa xor b, cuándoaybson 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
booles solo una subclase deint, pero se implementa para tener solo los valores0y1. Y xor lógico es equivalente a xor bit a bit cuando el dominio está restringido a0y1.Entonces la
logical_xorfunció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
operatormó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 importadaoperatores solo una forma funcional de un operador infijo incorporado existente.booltipo se sobrecarga__xor__para devolver booleanos. Funcionará bien, pero es excesivo cuandobool(a) ^ bool(b)hace exactamente lo mismo.^operador llama__xor__internamente.booltipo 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 == 3le da la espaldaTrue, mientras queTrue + True + False + True == 1da 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 ^ Truefunciona 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 seaFalsemás de unoTrue, lo que funciona si la condición lo comprueba== 1.or::A or BdevuelveAsibool(A)esTrue, de lo contrario devuelveBand::A and BdevuelveAsibool(A)esFalse, de lo contrario devuelveBPara 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,boFalse:fuente
andyorno devolverán el valor lógico.'foo' and 'bar'vuelve'bar'...xorimplementación que es coherente con el incorporadoandyor. Sin embargo, por supuesto, en situaciones prácticas,bool(a) ^ bool(b)o inclusoa ^ b(siaybson 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 truthen la parte superior del módulo y probartruth(a) != truth(b).boolser un constructor tiene una sobrecarga inevitable en el nivel C (debe aceptar argumentos como el equivalente*args, **kwargsy analizartupleydictextraerlos), dondetruth(siendo una función) puede usar una ruta optimizada que no requiere untupleo adict, y se ejecuta en aproximadamente la mitad del tiempo de lasboolsoluciones basadas (pero aún más tiempo que lasnotsoluciones 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 ^ bes polimorfo Siaybsonboolinstancias, 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 tiposbooly losinttipos. Nota:True ^ 2es3, demostrando cómo es de hecho bit a bit.bool ^ intcaso es poner todo enintprimer lugar. Aún así, Python ha incorporado el^operador para muchos bitsinty 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 usarFalseen esas líneas.Exclusivo O se define de la siguiente manera
fuente
andyorhacer cortocircuito. Cualquierxorimplementación no puede provocar un cortocircuito, por lo que ya existe una discrepancia; por lo tanto, no hay razón para quexorfuncione comoand+ordo.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á
asibes falsodará
bsiaes falsodará
FalsecontrarioO 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
xorimplementación que devuelveTrueoFalsees 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
xorfunció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,
boolsu 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