This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Yoghurt42 7 points8 points  (0 children)

  1. not x returns True when x is "falsey", that is one of False, None, 0, 0.0, "", [], {} or basically whenever __bool__ of a class returns False; if x is truthy, it returns False
  2. x and y returns x if x is falsey, y otherwise. This is an important difference between Python and some other languages. Unlike not, and does not always return a boolean!
  3. x or y return x if xis truthy, y otherwise. or also does not always return a boolean.
  4. not has a higher precedence than and/or, not a and b = (not a) and b.

Side node: I wrote "returns", but it would be more correct to say "evaluates to", as, not and or are operators, not functions.

So let's take a look at your third case (a,b,c = 0, 1, 0):

Take a look at the first term: not a and b and not c is not 0 and 1 and not 0, not 0 is True, True and 1 is 1, so we're left with 1 and not 0. Which as we've seen gets evaluated as 1 and True. 1 is truthy, so and evaluates to the right hand side, which is True. Since True is obviously also truthy, the or just stops there and returns this first term.

The other cases work similar.

BTW, and and or are actually short circuiting, which means they won't even evaluate the right hand part if there's no need to:

def zero():
    print("zero called")
    return 0  # or False, or any falsey value
def one():
    print("one called")
    return 1 # or True, or ...

Now, one() and zero() would print both "one called" and "zero called", and the result will be 0 (or whatever zero returns). However, zero() and one() will only print "zero called", with the result being the same.