How to test multiple variables against a value?
You misunderstand how boolean expressions work; they don't work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:
if x == 1 or y == 1 or z == 1:
x
and y
are otherwise evaluated on their own (False
if 0
, True
otherwise).
You can shorten that using a containment test against a tuple:
if 1 in (x, y, z):
or better still:
if 1 in {x, y, z}:
using a set
to take advantage of the constant-cost membership test (in
takes a fixed amount of time whatever the left-hand operand is).
When you use or
, python sees each side of the operator as separate expressions. The expression x or y == 1
is treated as first a boolean test for x
, then if that is False, the expression y == 1
is tested.
This is due to operator precedence. The or
operator has a lower precedence than the ==
test, so the latter is evaluated first.
However, even if this were not the case, and the expression x or y or z == 1
was actually interpreted as (x or y or z) == 1
instead, this would still not do what you expect it to do.
x or y or z
would evaluate to the first argument that is 'truthy', e.g. not False
, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context).
So for the values x = 2; y = 1; z = 0
, x or y or z
would resolve to 2
, because that is the first true-like value in the arguments. Then 2 == 1
would be False
, even though y == 1
would be True
.
The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3
would fail for the same reasons. Use x == 1 or x == 2 or x == 3
or x in {1, 2, 3}
.
Your problem is more easily addressed with a dictionary structure like:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
As stated by Martijn Pieters, the correct, and fastest, format is:
if 1 in {x, y, z}:
Using his advice you would now have separate if-statements so that Python will read each statement whether the former were True
or False
. Such as:
if 0 in {x, y, z}:
mylist.append("c")
if 1 in {x, y, z}:
mylist.append("d")
if 2 in {x, y, z}:
mylist.append("e")
...
This will work, but if you are comfortable using dictionaries (see what I did there), you can clean this up by making an initial dictionary mapping the numbers to the letters you want, then just using a for-loop:
num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
if number in {x, y, z}:
mylist.append(num_to_letters[number])