2

im curious about how the logical operators work in sets. cosider this:

x = set('abcde')
y = set('bdxyz')

# union
print(x | y) # output: {'d', 'b', 'y', 'e', 'z', 'x', 'c', 'a'}
print(x or y) # output: {'d', 'b', 'e', 'c', 'a'} 

# intersection
print(x and y) # output: {'d', 'b', 'y', 'z', 'x'}
print(x & y) # output: {'b', 'd'}

i expected the outputs for union and intersection to be the same for each. how is it possible that they are not? can anyone explain?

  • Because the bitwise operators are distinct from the boolean logical operators, I don't know why you *expected* them to be the same. Also, your output is incorrect for the union. The logical operator should be first – juanpa.arrivillaga Jul 27 '18 at 19:58
  • 2
    This has nothing to do with the operands being `set`s. This is how `and` and `or` work for all types. Try `1 or 2` and `50 or 0`. – Patrick Haugh Jul 27 '18 at 19:58
  • 2
    `x or y` is not the same as `x | y`. The latter is the the union for sets. The former is saying return the first Truthy value. – pault Jul 27 '18 at 19:58
  • I'm a little surprised that `or` and `&` produce expected output while `|` and `and` don't. I'd think it'd be one pair or another. – ggorlen Jul 27 '18 at 20:00
  • @ggorlen that just happens to be the case. – Matthew Story Jul 27 '18 at 20:03
  • 1
    @MatthewStory actually, it doesn't--OP just typed it in wrong: https://repl.it/repls/BaggyAmusedBlock – ggorlen Jul 27 '18 at 20:05
  • @ggorlen ah .. :shrug:, in any case these operators have no relationship to one-another. – Matthew Story Jul 27 '18 at 20:08
  • 1
    @MatthewStory I agree. I was mostly sucked in to this post because of the inconsistent output. If Python actually worked that way, I'd barf. It's very upsetting. – ggorlen Jul 27 '18 at 20:16

2 Answers2

7

You cannot override the functionality of logical and and or in python. So when you call:

>>> set([1, 2, 3]) or set([2, 3, 4])
{1, 2, 3}

It's treating it as logical or, which would evaluate the left side to boolean true and immediately stops evaluating and returns the left side. Similarly:

>>> set([1, 2, 3]) and set([2, 3, 4])
{2, 3, 4}

Is treated as a logical and, which would evaluate the left side to boolean True and then evaluate the right side to boolean True resulting in the right side being returned.

Logical and and or have no relationship to bitwise & and | in any language, python included.

Matthew Story
  • 3,573
  • 15
  • 26
3

I guess it's better to illustrate with an example.

or returns the first value that evaluates as True

# any non-zero integer is True
1 or 0 => 1
0 or 1 or 2 => 1
0 or 0 or 2 => 2

since non-empty set x is evaluated as True

x or y => x  which is {'d', 'b', 'e', 'c', 'a'} 

Meanwhile and need to evaluate all the expressions and only when all the expressions are evaluated as True, it returns the last one.

1 and 2 => 2
1 and 'a' and (1, 2, 3) => (1, 2, 3)

since both x and y can be evaluated as True

x and y => y  which is {'d', 'b', 'y', 'z', 'x'}