# Why can't I xor strings?

Phil Frost indigo at bitglue.com
Fri Oct 8 23:07:43 CEST 2004

```On Fri, Oct 08, 2004 at 04:57:13PM -0400, dataangel wrote:
> Phil Frost wrote:
>
> >^ is the bitwise xor operator. Performing bitwise operations on strings
> >doesn't make much sense, so it's invalid. You can define a logical xor
> >function like so:
> >
> >xor = lambda p, q: (p and not q) or (not p and q)
> >
> >or equivalently:
> >
> >xor = lambda p, q: bool(p) != bool(q)
> >
> >On Fri, Oct 08, 2004 at 04:19:22PM -0400, dataangel wrote:
> >
> >
> >>I wrote a function to compare whether two strings are "similar" because
> >>I'm using python to make a small text adventure engine and I want to it
> >>to be responsive to slight mispellings, like "inevtory" and the like. To
> >>save time the first thing my function does is check if I'm comparing an
> >>empty vs. a non-empty string, because they are to be never considered
> >>similar. Right now I have to write out the check like this:
> >>
> >>  if str1 and str2:
> >>      if not str1 or not str2:
> >>          return 0
> >>
> >>Because python won't let me do str1 ^ str2. Why does this only work for
> >>numbers? Just treat empty strings as 0 and nonempty as 1.
> >>
> >>Regardless of whether this is the best implementation for detecting if
> >>two strings are similar, I don't see why xor for strings shouldn't be
> >>supported. Am I missing something? Inparticular, I think it'd be cool to
> >>have "xor" as opposed to "^". The carrot would return the resulting
> >>value, while "xor" would act like and/or do and return the one that was
> >>true (if any).
>
>
> Urk, ran into a little trouble with your code (the first one):
>
> >>> xor("", "") == False
> False
> >>> xor("", "") == True
> False
>
> I'm a python newbie so I'm not sure how something can niether evaluate
> to be true nor false at the same time :P Bug?

Sorry, I didn't read your problem well enough. False xor False == False
by definition; the problem is that xor is not what you want. In your
example:

if str1 and str2:
if not str1 or not str2:
return 0

"return 0" will never be reached. In order for "str1 and str2" to be
true, both strings must be not empty. Your test within that, "if not
str1 or not str2" says "if either string is empty...", which isn't
possible, since you just tested that neither is empty. What you probably
want is this:

if not (str1 and str2):
# at least one string is empty

```