5

While reading about logical operators in python, I came across the following expressions:

5 and 1 

output: 1

5 or 1 

output: 5

Can anyone explain how this is working?
I know that the operands of the logical operators are Boolean

Neuron
  • 5,141
  • 5
  • 38
  • 59
BoRRis
  • 983
  • 8
  • 23
  • Those are the same results are bitwise operations. Probably just a coincidence – OneCricketeer Jun 18 '17 at 05:56
  • 1
    These are logical operators and you may just see them as logical entities. In this case, short circuiting happens. So in the event of or, 1 or 5 is 1. Doesn't check 5. In case of 5 or 1, result is 5(1 is not checked). In case of and, the later argument is returned. 1 and 5 = 5 while 5 and 1 = 1 – user2685079 Jun 18 '17 at 06:04
  • It is also worth trying `1 and 5` and `1 or 5` which return 5 & 1 respectively and make it a little clearer that the condition is being evaluated rather than the bitwise result. – Steve Barnes Jun 18 '17 at 06:23
  • To understand this even further, I suggest you do some light reading on Discrete Mathematics and Propositional Logic; [this](http://www2.fiit.stuba.sk/~kvasnicka/Mathematics%20for%20Informatics/Rosen_Discrete_Mathematics_and_Its_Applications_7th_Edition.pdf) is a good reference if you have the time. – pstatix Jun 18 '17 at 07:02

4 Answers4

11

that is well documented:

x or y      if x is false, then y, else x 
x and y     if x is false, then x, else y 

both short-circuit (e.g. or will not evaluate y if x is truthy).

the documentation also states what is considered falsy (False, 0, None, empty sequences/mappings, ...) - everything else is considered truthy.

a few examples:

7 and 'a'             # -> 'a'
[] or None            # -> None
{'a': 1} or 'abc'[5]  # -> {'a': 1}; no IndexError raised from 'abc'[5]
False and 'abc'[5]    # -> False; no IndexError raised from 'abc'[5]

note how the last two show the short-circuit behavior: the second statement (that would raise an IndexError) is not executed.

your statement that the operands are boolean is a bit moot. python does have booleans (actually just 2 of them: True and False; they are subtypes of int). but logical operations in python just check if operands are truthy or falsy. the bool function is not called on the operands.


the terms truthy and falsy seem not to be used in the official python documentation. but books teaching python and the community here do use these terms. there is a discussion about the terms on english.stackexchange.com and also a mention on wikipedia.

hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
1

This is because of the short-circuit evaluation method.

For the and, all of the clauses must be True, so all of them must be evaluated. Once a False is encountered, the whole thing evaluates to False, we don't even need to evaluate the next ones.

>>> 1 and 2
2
>>> 2 and 1
1
>>> 1 and 2 and 3
3
>>> 1 and 0 and 2
0
>>> 0 and 1 and 2
0

But for or, any of the clauses being evaluated to True is enough for the whole thing to be True. So once it finds something to be True, the value of the whole thing is decided to be True, without even evaluating the subsequent clauses.

>>> 0 or 1
1
>>> 1 or 0
1
>>> 1 or 2
1
>>> 2 or 1
2
>>> 0 or 0 or 1
1
>>> 0 or 1 or 2
1
Sufian Latif
  • 13,086
  • 3
  • 33
  • 70
0

This is called short circuiting or lazy evaluation. Example, if you have "a or b" and a meets the criteria, then python will output it. Conversely, if you have "a and b" and "a" does not meet the criteria, then python will stop evaluating it since it cannot be satisfied.

0

In the first case when the and keyword is there, it is the second value that determines whether it is logically true or not, provided the first number is non-zero. Thus the second value is printed eventually.

In the second case, the keyword is or so when the first non-zero operand is encountered, since it makes the statement logically true, it is printed onto the output screen.

It is an example of lazy evaluation.