-2

I am trying to understand that bit of code:

s = list()
r = string()
# actual bit of code:
print(s and 'ERROR' or r or 'EMPTY')

What this does:

  • if s is not an empty list, then you must print 'ERROR'
  • else if r is not an empty string you must print r
  • else print 'EMPTY'

I am now trying to understand why this works, and more widely how you can use logical operators in expressions, like in this example.

vale075
  • 9
  • 3
  • 2
    Focus on "using logical operators in an expression" rather than "...in a print statement" and you'll probably find more useful search results. – larsks Apr 29 '22 at 13:45
  • You should really never use code like this. `some_variable or []` would be fine, but more than one operator is too much imho. – luk2302 Apr 29 '22 at 13:45
  • `"abc" and "bcd"` -> `"bcd"` and `'' and "bcd"` -> `''`. `'' or "bcd"` -> `"bcd"`, `"abc" or "bcd"` -> `"abc"`. From python docs [boolean operators](https://docs.python.org/3/reference/expressions.html#boolean-operations) – Ch3steR Apr 29 '22 at 13:48
  • @luk2302 This is a very particular context: a contest where the code needed to be as small as possible. I like those because you learn the limits of python thanks to them. – vale075 May 01 '22 at 14:23
  • Then ask e.g. on codegolf, but not on SO. And you do not learn any python limits, you primarily learn how to write unmaintainable and unreadable code. Sure, you learn some concepts too but there are easier ways of learning those. – luk2302 May 01 '22 at 14:27

3 Answers3

0

x and y is x if it is "false-y" (i.e. 0, False, None, [], '', ...), otherwise it is y.
x or y is x if it is "truth-y", otherwise it is y.

That is, x or y is the same as x if x else y, and x and y the same as x if not x else y.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
0

If s is non-empty, s and 'ERROR' produces the truthy value 'ERROR', which short-circuited the rest of the or expression.

If s is empty, s and 'ERROR' produces the false value [], which leads to the evaluation of r to determine if the value of the entire expression is r or EMPTY.

It helps to play with smaller examples using non-Boolean arguments to see how both and and or work.

>>> [] and "ERROR"
[]
>>> ["foo"] and "ERROR"
"ERROR"

It might be clearer to use the conditional expression here:

print("ERROR" if s else (r or "EMPTY"))

or just use a "naive" if statement.

if s:
    print("ERROR")
elif r:
    print(r)
else:
    print("EMPTY")
chepner
  • 497,756
  • 71
  • 530
  • 681
0

This is a question more focused on logical operators and Short-circuit evaluation . Firstly, you need to understand that every variable has a boolean value associated with it.

An empty list is false, a list with a length of 1 or higher is true. This can be checked with the bool() operator:

>>> bool([])
False
>>> bool(['a'])
True

Similarly, an empty string is false and a string of one or more characters is true.

>>> bool('')
False
>>> bool('string')
True

The expression s and 'ERROR' or r or 'EMPTY' is evaluated as follows:

  1. bool(s) and bool('ERROR')
  2. or
  3. bool(r)
  4. or
  5. bool('EMPTY')

When any of these is True, the evaluation ends. It's merely the order of evaluation.

Rafael de Bem
  • 641
  • 7
  • 15