3

The if statement below succeeds and the value of s is printed. However if you remove the : and/or whitespace conditionals it then fails. I am confused as to why it is succeeding in the first place.

    s="( )"
    if ("if" and ":" and " ") in s:
        print(s)
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
jlEe
  • 41
  • 2

3 Answers3

10

The stuff in the parentheses is an expression that evaluates to a single value:

>>> "if" and ":" and " "
' '
>>> _ in "( )"
True
>>> ' ' in "( )"
True
>>> ("if" and ":" and " ") == ' '
True

and is like the ordinary boolean AND, but on steroids:

>>> 0 and 0
0
>>> 0 and 1
0
>>> 1 and 0
0
>>> 1 and 1
1
>>> 0 and 'hello'
0
>>> 'hello' and 0
0
>>> 'hello' and 'hello'
'hello'  # WAIT. That's illegal!

So, and returns the last truthy object in a chain of truthy objects (or the first non-truthy object it encounters). Notice that it returns an object, not strictly a boolean, like a binary AND would.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
0

Take a look at what happens if you just run:

"if" and ":" and " "

You'll get:

" "

This is because you are first evaluating everything in the parentheses, then checking if the result of that is in s

To evaluate what you're looking for, you'll need something like:

if "if" in s and ":" in s and " " in s:
    print(s)

Alternatively:

if all(["if" in s, ":" in s, " " in s]):
    print(s)
0
a and b returns b if a is True, else returns a

So when we do "if" and ":" and " " is equivalent to ("if" and ":") and " "

  • "if" and ":" is ":"
  • ":" and " " is " "

So, "if" and ":" and " " is " " . Given s="( )" and the result " " is inside s="( )" Thats why print(s) is printed

Note " " is true meanwhile "" is false