Comment obtenir le xor logique de deux variables en Python?

648

Comment obtenir le xor logique de deux variables en Python?

Par exemple, j'ai deux variables qui devraient être des chaînes. Je veux tester qu'un seul d'entre eux contient une valeur True (n'est pas None ou la chaîne vide):

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
    print "ok"
else:
    print "bad"

L' ^opérateur semble être au niveau du bit et n'est pas défini sur tous les objets:

>>> 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'
Zach Hirsch
la source
3
Comment définissez-vous "xor" pour quelques chaînes? Que pensez-vous que "abc" ^ "" devrait renvoyer ce qu'il ne fait pas?
Mehrdad Afshari
18
Il doit retourner True, plutôt que de lever une exception, car une seule des chaînes est True telle que définie par le type bool de Python normal.
Zach Hirsch
38
Je suis étonné que Python n'ait pas d'opérateur d'infixe appelé "xor", ce qui serait l'implémentation Pythonique la plus intuitive. L'utilisation de "^" est cohérente avec d'autres langages, mais pas aussi clairement lisible que la plupart de Python.
Mark E. Haase
13
@MehrdadAfshari La réponse évidente à votre question est celle qui a xor aest définie comme (a and not b) or (not a and b), et donc a xor b, quand aet bsont des chaînes de caractères, ou tout autre type, devraient donner n'importe quel (a and not b) or (not a and b)rendement.
Kaz
1
Le problème est que la documentation est pauvre. ^ est "bitwise exclusif ou", ce qui signifie littéralement bit par bit, et non bool par bool. donc x'FFFF00 '^ x'FFFF00' devrait être x'000000 '. Ou est-ce uniquement destiné à se produire au cas par cas? jeté comme des nombres? Nous devons itérer les caractères de chaîne plus courts pour correspondre à la longueur de la chaîne plus longue. Tout cela devrait être intégré.
mckenzm

Réponses:

1188

Si vous normalisez déjà les entrées en booléens, alors! = Est xor.

bool(a) != bool(b)
A. Coady
la source
148
Bien que ce soit intelligent et court, je ne suis pas convaincu que ce soit propre. Lorsque quelqu'un lit cette construction dans le code, est-il immédiatement évident pour eux qu'il s'agit d'une opération xor? Je me suis senti obligé d'ajouter un commentaire - un signe pour moi que j'écris du code peu clair et d'essayer de m'excuser avec un commentaire.
47
Peut-être "est-il clair que c'est un XOR?" est la mauvaise question. Nous essayions juste de voir si la réponse à deux questions était la même et nous pensions utiliser XOR pour l'implémenter. Par exemple, si nous voulons nous assurer que nous ne comparons pas les pommes aux oranges, est-ce que "si xor (isApple (x), isApple (y))" est vraiment plus clair que "si isApple (x)! = IsApple (y)"? Pas à moi!
AmigoNico
106
Il y a un problème avec "! =" Comme xor. Vous vous attendriez probablement à ce que bool (a)! = Bool (b)! = Bool (c) soit le même que bool (a) ^ bool (b) ^ bool (c). Il en va de même pour les jets, mais je recommanderais ^. Pour savoir ce qui se passe dans le premier exemple, recherchez "chaînage d'opérateur".
elmo
19
@elmo: +1 pour avoir souligné la différence, et +1 pour m'apprendre ce qu'est le chaînage d'opérateur! Je suis dans le camp qui dit que! = N'est pas aussi lisible que ^.
Mark E. Haase
13
devrait-il être à la bool(a) is not bool(b)place?
RNA
485

Vous pouvez toujours utiliser la définition de xor pour le calculer à partir d'autres opérations logiques:

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

Mais c'est un peu trop verbeux pour moi, et ce n'est pas particulièrement clair à première vue. Une autre façon de procéder est:

bool(a) ^ bool(b)

L'opérateur xor sur deux booléens est un xor logique (contrairement aux entiers, où il est au niveau du bit). Ce qui est logique, car booln'est qu'une sous-classe deint , mais est implémenté pour n'avoir que les valeurs 0et 1. Et xor logique est équivalent à xor au niveau du bit lorsque le domaine est limité à 0et 1.

Ainsi, la logical_xorfonction serait implémentée comme:

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

Nous remercions Nick Coghlan sur la liste de diffusion Python-3000 .

Zach Hirsch
la source
7
excellent article, mais de toutes les façons de nommer vos paramètres, pourquoi 'str1' et 'str2'?
SingleNegationElimination
1
@Token pourquoi pas. Voulez-vous dire parce qu'ils ne sont pas très pythoniques?
orokusaki
1
@Zach Hirsch Pourriez-vous utiliser (pas a et b) au lieu de (b et pas a) pour plus de lisibilité ou la définition serait-elle incompatible avec xor.
orokusaki
10
Vous devriez mettre les nots en premier comme ceci (not b and a) or (not a and b)afin qu'il retourne la chaîne s'il y en avait une, ce qui semble être la manière pythonique pour la fonction de fonctionner.
rjmunro
2
@TokenMacGuy: Que proposiez-vous qu'il devrait les nommer à la place?
user541686
180

Bitwise exclusive-or est déjà intégré à Python, dans le operatormodule (qui est identique à l' ^opérateur):

from operator import xor
xor(bool(a), bool(b))  # Note: converting to bools is essential
chant de loup-garou
la source
3
Voilà ce dont j'avais besoin. Lors du reverse engineering de logiciels malveillants, les chaînes sont souvent mutilées jusqu'à une opération XOR. En utilisant ce chr (xor (ord ("n"), 0x1A)) = 't'
ril3y
75
Attention, c'est aussi au niveau du bit: xor(1, 2)retourne 3. De la docstring: xor(a, b) -- Same as a ^ b. Rappelez-vous que tout ce qui est importé operatorn'est qu'une forme fonctionnelle d'un opérateur d'infixe intégré existant.
askewchan
5
@askewchan: Le booltype surcharge __xor__pour renvoyer des booléens. Cela fonctionnera très bien, mais sa surpuissance bool(a) ^ bool(b)fait exactement la même chose.
Martijn Pieters
@MartijnPieters L' ^opérateur appelle en __xor__interne.
Quantum7
5
@ Quantum7: oui, je ne sais pas pourquoi vous me dites cela. Je viens de dire que le booltype implémente la __xor__méthode spécifiquement parce ^qu'il l'appelle . Le fait étant que cela bool(a) ^ bool(b)fonctionne bien, il n'est pas nécessaire d'utiliser la operator.xor()fonction ici.
Martijn Pieters
43

Comme Zach l'a expliqué, vous pouvez utiliser:

xor = bool(a) ^ bool(b)

Personnellement, je privilégie un dialecte légèrement différent:

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

Ce dialecte est inspiré d'un langage de diagramme logique que j'ai appris à l'école où "OU" était désigné par une boîte contenant ≥1(supérieur ou égal à 1) et "XOR" était désigné par une boîte contenant =1.

Cela présente l'avantage d'implémenter correctement des opérandes exclusifs ou multiples.

  • "1 = a ^ b ^ c ..." signifie que le nombre d'opérandes vrais est impair. Cet opérateur est "parité".
  • "1 = a + b + c ..." signifie exactement qu'un opérande est vrai. C'est "exclusif ou", ce qui signifie "l'un à l'exclusion des autres".
ddaa
la source
12
Ainsi, True + True + False + True == 3 et 3! = 1, mais True XOR True XOR False XOR True == True. Pouvez-vous élaborer sur "l'implémentation correcte de XOR sur plusieurs opérandes"?
tzot
3
@tzot Votre exemple échoue, car selon la solution de ddaa, vous n'appliquez l'addition que sur deux variables à la fois. Donc, la bonne façon de tout écrire devrait être (((((True + True)==1)+False)==1)+True)==1. La réponse donnée ici se généralise totalement à plusieurs opérandes.
le
6
En outre, il existe une différence entre un XOR à trois voies et un ensemble de deux XOR regroupés par ordre d'opérations. Donc 3-WAY-XOR (A, B, C) n'est pas la même chose que XOR (XOR (A, B), C). Et l'exemple de ddaa est le premier, tandis que le vôtre suppose le second.
le
3
@ Mr.F Votre explication n'excuse pas vraiment cette réponse. En Python, si vous venez de faire True + True + False + True, vous n'obtenez et Redonne en redonne . En d'autres termes, la réponse ici ne se généralise pas correctement; pour cela, vous devez effectuer un travail supplémentaire. En attendant un simple fonctionne comme prévu. 3True + True + False + True == 3TrueTrue + True + False + True == 1FalseTrue ^ True ^ False ^ True
jpmc26
3
@ jpmc26 Je ne comprends pas votre commentaire. L'approche par addition vise à généraliser l'opération dans laquelle vous voulez vérifier qu'il s'agit exactement d'un opérande True, un XOR multi-arité. Il s'agit d'une opération différente de celle par exemple A XOR B XOR ... XOR Z. En d'autres termes, si vous prévoyez d'utiliser la version basée sur des ajouts, les opérandes True + True + False + Truedoivent alors s'attendre à ce que le résultat soit Falsesupérieur à l'un d'eux True, ce qui fonctionne si la condition vérifie == 1.
ely
26
  • Python logique or:: A or Bretourne Asi bool(A)est True, sinon retourneB
  • Python logique and:: A and Bretourne Asi bool(A)est False, sinon retourneB

Pour garder la plupart de cette façon de penser, ma définition logique xor serait:

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

De cette façon , il peut revenir a, bou False:

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'
nosklo
la source
5
Cela me semble mauvais, ou du moins bizarre. Aucun des autres opérateurs logiques intégrés ne renvoie l'une des trois valeurs possibles.
Zach Hirsch
2
@Zach Hirsch: C'est pourquoi j'ai dit "de garder la plupart de cette façon de penser" - car il n'y a pas de bon résultat quand les deux sont vrais ou faux
nosklo
L'opération logique doit renvoyer une valeur logique, donc le deuxième "retour a ou b" semble étrange, donc le deuxième retour doit retourner True.
Denis Barmenkov
9
@Denis Barmenkov: Eh bien, notez que les opérateurs logiques de python andet orne reviendra pas valeur logique. 'foo' and 'bar'retourne 'bar'...
nosklo
6
A première vue, les 2 réponses précédentes semblent être le meilleur, mais à la réflexion, celui - ci est en fait le seul vraiment bon, soit il est le seul qui donne un exemple d'une xormise en œuvre cohérente avec le haut- andet or. Cependant, bien sûr, dans des situations pratiques, bool(a) ^ bool(b)ou même a ^ b(si aet bsont connus pour être bool) sont plus concis bien sûr.
Erik Kaplun
23

J'ai testé plusieurs approches et j'ai not a != (not b)semblé être la plus rapide.

Voici quelques tests

%timeit not a != (not b)
10000000 loops, best of 3: 78.5 ns per loop

%timeit bool(a) != bool(b)
1000000 loops, best of 3: 343 ns per loop

%timeit not a ^ (not b)
10000000 loops, best of 3: 131 ns per loop

Modifier: les exemples 1 et 3 ci-dessus manquent de parenthèses, donc le résultat est incorrect. Nouveaux résultats + truth()fonction comme suggéré par ShadowRanger.

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns
Rugnar
la source
6
C'est 100 ns de ma vie, je ne reviendrai pas ;-)
Arel
4
Pour un timing intermédiaire, vous pouvez le faire from operator import truthen haut du module et tester truth(a) != truth(b). boolêtre un constructeur a beaucoup de surcharge inévitable au niveau C (il doit accepter les arguments comme l'équivalent de *args, **kwargset les analyser tupleet dictles extraire), où truth(étant une fonction) peut utiliser un chemin optimisé qui ne nécessite ni a tupleni a dict, et s'exécute dans environ la moitié du temps des boolsolutions basées (mais toujours plus longtemps que les notsolutions basées).
ShadowRanger
9

Fil de récompense:

Idée d'anode ... Il suffit d'essayer l'expression (peut-être) pythonique «n'est pas» pour obtenir le comportement du «xor» logique

La table de vérité serait:

>>> True is not True
False
>>> True is not False
True
>>> False is not True
True
>>> False is not False
False
>>>

Et pour votre exemple de chaîne:

>>> "abc" is not  ""
True
>>> 'abc' is not 'abc' 
False
>>> 'abc' is not '' 
True
>>> '' is not 'abc' 
True
>>> '' is not '' 
False
>>> 

Toutefois; comme ils l'ont indiqué ci-dessus, cela dépend du comportement réel que vous souhaitez retirer sur les chaînes de couple, car les chaînes ne sont pas boléennes ... et plus encore: si vous «Plongez dans Python», vous trouverez «La nature particulière de" et "et" ou "» http://www.diveintopython.net/power_of_introspection/and_or.html

Désolé mon anglais écrit, ce n'est pas ma langue d'origine.

Cordialement.

Agustin Marcos
la source
Je l'utilise aussi pour le lire comme "strictement différent". En effet, certains langages utilisent pour implémenter l'opération bit par bit de la représentation binaire et prennent le bool de l'opération bit à bit résultante. Je suppose que votre réponse est plus "à l'épreuve des balles" car elle s'étend au-delà de l'espace booléen.
yucer
Je veux dire le fait que votre réponse couvre le cas de la comparaison de Aucun, Faux '', car différent est l'élément distinctif. Par exemple: bool (False)! = Bool ('') néanmoins False is not '' "est plus d'accord avec cette sémantique du" strictement différent "
yucer
8

Python a un opérateur OU exclusif au niveau du bit, c'est ^:

>>> True ^ False
True
>>> True ^ True
False
>>> False ^ True
True
>>> False ^ False
False

Vous pouvez l'utiliser en convertissant les entrées en booléens avant d'appliquer xor ( ^):

bool(a) ^ bool(b)

(Modifié - merci Arel)

Tomer Gal
la source
Votre réponse doit indiquer clairement qu'il ^s'agit d'un xor au niveau du bit (pas un xor logique comme la question posée). bool(2) ^ bool(3)donne une réponse différente de bool(2 ^ 3).
Arel
1
@Arel Mais ce n'est pas le cas. a ^ best polymorphe. Si aet bsont des boolinstances, le résultat sera boolégalement. Ce comportement peut difficilement être appelé un xor "au niveau du bit".
Alfe
@Alfe le point important est que les valeurs doivent d'abord être converties en booléens. Les définit de documentation Python ^comme, même si au niveau du bit , il est un point intéressant que les types sont conservés pour boolet inttypes. Remarque: True ^ 2est 3, démontrant comment il est en effet au niveau du bit.
Arel
@Arel Oui, le bool ^ intcas est en quelque sorte de tout jeter en intpremier. Pourtant, Python a intégré l' ^opérateur pour de nombreux bits dans intet pour le bit représenté dans a bool, donc les deux sont au niveau du bit , mais le xor au niveau du bit pour un seul bit est juste le xor logique pour les booléens.
Alfe
Je déteste toujours utiliser cet opérateur, même si je comprends que xor, venant d'un milieu d'ingénierie, cela me semble instinctivement comme une puissance mathématique, 2^3 = pow(2,3)ce qui signifie que je commente toujours explicitement pour éviter toute confusion.
Nicholas Hamilton
8

Comme je ne vois pas la simple variante de xor utilisant des arguments variables et uniquement une opération sur les valeurs de vérité True ou False, je vais la jeter ici pour que quiconque puisse l'utiliser. C'est comme noté par d'autres, assez (pour ne pas dire très) simple.

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

Et l'utilisation est également simple:

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

Comme il s'agit du XOR logique n-aire généralisé, sa valeur de vérité sera True chaque fois que le nombre d'opérandes True est impair (et pas seulement quand exactement un est True, ce n'est qu'un cas dans lequel le XOR n-aire est True).

Ainsi, si vous êtes à la recherche d'un prédicat n-aire qui n'est vrai que lorsque l'un de ses opérandes est exactement, vous pouvez utiliser:

def isOne(*vars):
    sum = False
    for v in vars:
        if sum and v:
            return False
        else:
            sum = sum or v
    return sum
micdah
la source
Pour améliorer cette réponse: (bool(False) is False) == True. Vous pouvez simplement utiliser Falsesur ces lignes.
pathunstrom
7

Exclusif Or est défini comme suit

def xor( a, b ):
    return (a or b) and not (a and b)
S.Lott
la source
2
cela retournerait True pour xor ('ceci', '') et pour suivre la voie de python, il devrait retourner 'ceci'.
nosklo
@nosklo: Prenez-le avec le BDFL, s'il vous plaît, pas moi. Étant donné que Python renvoie True, cela doit être la manière de Python.
S.Lott
2
Je veux dire pour la cohérence avec les autres opérateurs logiques python - Python ne retourne pas True quand je le fais ('ceci' ou ''), il retourne 'ceci'. Mais dans votre fonction, xor ('this', '') renvoie True. Il devrait retourner 'this' comme le fait le "ou" python.
nosklo
10
Python andet orfaire un court-circuit. Toute xormise en œuvre ne peut pas court-circuiter, il y a donc déjà un écart; par conséquent, il n'y a aucune raison qui xordevrait fonctionner comme and+ ordo.
tzot
7

Parfois, je me retrouve à travailler avec 1 et 0 au lieu des valeurs booléennes True et False. Dans ce cas, xor peut être défini comme

z = (x + y) % 2

qui a la table de vérité suivante:

     x
   |0|1|
  -+-+-+
  0|0|1|
y -+-+-+
  1|1|0|
  -+-+-+
Steve L
la source
7

Je sais que c'est tard, mais j'ai eu une pensée et ça pourrait valoir la peine, juste pour la documentation. Peut-être que cela fonctionnerait: np.abs(x-y)L'idée est que

  1. si x = True = 1 et y = False = 0 alors le résultat serait | 1-0 | = 1 = True
  2. si x = Faux = 0 et y = Faux = 0 alors le résultat serait | 0-0 | = 0 = Faux
  3. si x = True = 1 et y = True = 1, le résultat serait | 1-1 | = 0 = False
  4. si x = False = 0 et y = True = 1 alors le résultat serait | 0-1 | = 1 = True
BarocliniCplusplus
la source
7

Simple, facile à comprendre:

sum( (bool(a), bool(b) ) == 1

Si un choix exclusif est ce que vous recherchez, il peut être étendu à plusieurs arguments:

sum( bool(x) for x in y ) % 2 == 1
cz
la source
1
sum(map(bool, y)) % 2 == 1
warvariuc
6

Que dis-tu de ça?

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

donnera asi best faux
donnera bsi aest faux
donnera Falseautrement

Ou avec l'expression ternaire Python 2.5+:

(False if a else b) if b else a
Markus Jarderot
la source
6

Certaines des implémentations suggérées ici entraîneront une évaluation répétée des opérandes dans certains cas, ce qui peut entraîner des effets secondaires involontaires et doit donc être évité.

Cela dit, une xorimplémentation qui renvoie soit Trueou Falseest assez simple; celui qui renvoie l'un des opérandes, si possible, est beaucoup plus délicat, car il n'y a pas de consensus quant à l'opérande qui doit être choisi, surtout lorsqu'il y a plus de deux opérandes. Par exemple, devrait xor(None, -1, [], True)revenir None, []ou False? Je parie que chaque réponse apparaît à certaines personnes comme la plus intuitive.

Pour le résultat True ou False, il y a jusqu'à cinq choix possibles: retourner le premier opérande (s'il correspond au résultat final en valeur, sinon booléen), retourner la première correspondance (s'il en existe au moins un, sinon booléen), retourne le dernier opérande (si ... sinon ...), retourne la dernière correspondance (si ... sinon ...), ou retourne toujours booléen. Au total, cela fait 5 ** 2 = 25 saveurs de 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()

la source
5

Beaucoup de gens, y compris moi-même, ont besoin d'une xorfonction qui se comporte comme un circuit xor à n entrées, où n est variable. (Voir https://en.wikipedia.org/wiki/XOR_gate ). La fonction simple suivante implémente cela.

def xor(*args):
   """
   This function accepts an arbitrary number of input arguments, returning True
   if and only if bool() evaluates to True for an odd number of the input arguments.
   """

   return bool(sum(map(bool,args)) % 2)

Voici un exemple d'E / S:

In [1]: xor(False, True)
Out[1]: True

In [2]: xor(True, True)
Out[2]: False

In [3]: xor(True, True, True)
Out[3]: True
Phillip M. Feldman
la source
5

Pour obtenir le xor logique de deux ou plusieurs variables en Python:

  1. Convertir les entrées en booléens
  2. Utilisez l'opérateur xor au niveau du bit ( ^ou operator.xor)

Par exemple,

bool(a) ^ bool(b)

Lorsque vous convertissez les entrées en booléens, xor au niveau du bit devient xor logique .

Notez que la réponse acceptée est fausse: != n'est pas la même chose que xor en Python en raison de la subtilité du chaînage des opérateurs .

Par exemple, le xor des trois valeurs ci-dessous est incorrect lors de l'utilisation !=:

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

(PS J'ai essayé de modifier la réponse acceptée pour inclure cet avertissement, mais ma modification a été rejetée.)

Arel
la source
4

C'est facile quand vous savez ce que fait XOR:

def logical_xor(a, b):
    return (a and not b) or (not a and b)

test_data = [
  [False, False],
  [False, True],
  [True, False],
  [True, True],
]

for a, b in test_data:
    print '%r xor %s = %r' % (a, b, logical_xor(a, b))
Denis Barmenkov
la source
4

Ceci obtient le XOR logique exclusif pour deux (ou plus) variables

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")

any([str1, str2]) and not all([str1, str2])

Le premier problème avec cette configuration est qu'elle traverse très probablement toute la liste deux fois et, au minimum, vérifiera au moins un des éléments deux fois. Il peut donc augmenter la compréhension du code, mais il ne se prête pas à la vitesse (qui peut différer de manière négligeable selon votre cas d'utilisation).

Le deuxième problème avec cette configuration est qu'elle vérifie l'exclusivité quel que soit le nombre de variables. C'est peut-être au premier abord considéré comme une caractéristique, mais le premier problème devient beaucoup plus important à mesure que le nombre de variables augmente (si jamais elles le font).

Marc
la source
4

Xor est ^en Python. Il renvoie:

  • Un xor au niveau du bit pour les pouces
  • Xor logique pour bools
  • Une union exclusive pour les décors
  • Résultats définis par l'utilisateur pour les classes qui implémentent __xor__.
  • TypeError pour les types non définis, tels que les chaînes ou les dictionnaires.

Si vous avez l'intention de les utiliser sur des chaînes de toute façon, les intégrer boolrend votre opération sans ambiguïté (vous pouvez également signifier set(str1) ^ set(str2)).

Arthur Havlicek
la source
3

XOR est implémenté dans operator.xor.

lbolla
la source
8
operator.xor correspond à l'opération au niveau du bit, que c'est celle que l'affiche originale ne veut pas.
Niriel
@kojiro évidemment!
Arel
3

C'est ainsi que je coderais n'importe quelle table de vérité. Pour xor en particulier, nous avons:

| a | b  | xor   |             |
|---|----|-------|-------------|
| T | T  | F     |             |
| T | F  | T     | a and not b |
| F | T  | T     | not a and b |
| F | F  | F     |             |

Regardez simplement les valeurs T dans la colonne de réponse et enchaînez tous les vrais cas avec un ou logique. Donc, cette table de vérité peut être produite dans le cas 2 ou 3. Par conséquent,

xor = lambda a, b: (a and not b) or (not a and b)
snagpaul
la source
-6

Nous pouvons facilement trouver le xor de deux variables en utilisant:

def xor(a,b):
    return a !=b

Exemple:

xor (Vrai, Faux) >>> Vrai

Muhammad Abdullah
la source
1
ou xor("hey", "there")>>> Vrai, mais ce n'est pas ce que nous voulons
Mayou36