Why does a == x or y or z always evaluate to True? How can I compare a to all of those?
In many cases, Python looks and behaves like natural English, but this is one case where that abstraction fails. People can use context clues to determine that "Jon" and "Inbar" are objects joined to the verb "equals", but the Python interpreter is more literal minded.
if name == "Kevin" or "Jon" or "Inbar":
is logically equivalent to:
if (name == "Kevin") or ("Jon") or ("Inbar"):
Which, for user Bob, is equivalent to:
if (False) or ("Jon") or ("Inbar"):
The or
operator chooses the first argument with a positive truth value:
if "Jon":
And since "Jon" has a positive truth value, the if
block executes. That is what causes "Access granted" to be printed regardless of the name given.
All of this reasoning also applies to the expression if "Kevin" or "Jon" or "Inbar" == name
. the first value, "Kevin"
, is true, so the if
block executes.
There are two common ways to properly construct this conditional.
Use multiple
==
operators to explicitly check against each value:if name == "Kevin" or name == "Jon" or name == "Inbar":
Compose a collection of valid values (a set, a list or a tuple for example), and use the
in
operator to test for membership:if name in {"Kevin", "Jon", "Inbar"}:
In general of the two the second should be preferred as it's easier to read and also faster:
>>> import timeit
>>> timeit.timeit('name == "Kevin" or name == "Jon" or name == "Inbar"',
setup="name='Inbar'")
0.4247764749999945
>>> timeit.timeit('name in {"Kevin", "Jon", "Inbar"}', setup="name='Inbar'")
0.18493307199999265
For those who may want proof that if a == b or c or d or e: ...
is indeed parsed like this. The built-in ast
module provides an answer:
>>> import ast
>>> ast.parse("a == b or c or d or e", "<string>", "eval")
<ast.Expression object at 0x7f929c898220>
>>> print(ast.dump(_, indent=4))
Expression(
body=BoolOp(
op=Or(),
values=[
Compare(
left=Name(id='a', ctx=Load()),
ops=[
Eq()],
comparators=[
Name(id='b', ctx=Load())]),
Name(id='c', ctx=Load()),
Name(id='d', ctx=Load()),
Name(id='e', ctx=Load())]))
As one can see, it's the boolean operator or
applied to four sub-expressions: comparison a == b
; and simple expressions c
, d
, and e
.
Why is `!!(a||!a)` always true?
First off, !! expression
cancels out: it’s the same as expression
, because the negation of a negation is the original value.
So we’re left with a || ! a
, which is a disjunction. So the result is true
if at least one of the sub-expressions a
or !a
is true.
And lastly, a
is true if a
is true (duh). And ! a
is true if a
is false. Thus, regardless of the value of a
, the overall expression is true.
Can someone explain why print(red == blue or 3 = 3) returns True
When you use the Boolean Operator or, only one of the conditions declared has to be true in order for it to return true. 3>=3 is true, so the whole expression is true.
If statement not returning expected result
Your problem is with if score == 2 or 3
.
You can re-write that as (score == 2) or (3)
which resolves to False or True
or True or True
, which is always True.
This is a bit quirky of Python. bool(any_object)
returns True if the object is not None
. Try bool(3)
and see that you get True
from it.
What you meant to do is if (score == 2) or (score == 3)
or if score in [2, 3]
, either of those would work.
Why is my or statement not working as I want?
Instead of if repeat == "No" or "no"
, use:
if repeat == "No" or repeat == "no"
Or even:
if repeat in ("No", "no")
Related Topics
How to Get Monotonic Time Durations in Python
System-Wide Mutex in Python on Linux
What Does ** (Double Star/Asterisk) and * (Star/Asterisk) Do For Parameters
How to Pandas Group-By to Get Sum
What Exactly Do "U" and "R" String Prefixes Do, and What Are Raw String Literals
How to Print Curly-Brace Characters in a String While Using .Format
How to Add Sequential Counter Column on Groups Using Pandas Groupby
How to Change the Size of Figures Drawn With Matplotlib
Read Streaming Input from Subprocess.Communicate()
What's the Pythonic Way to Use Getters and Setters
Uninstall Python Built from Source
What Does If _Name_ == "_Main_": Do
Is There a Difference Between "==" and "Is"
Evaluating a Mathematical Expression in a String
Convert a String Representation of a Dictionary to a Dictionary
How to Detect Collisions Between Two Rectangular Objects or Images in Pygame