How to test multiple variables against a single value? | Python [Answered]

Problem:

I’m trying to make a function that will compare multiple variables to an integer and output a string of three letters. I was wondering if there was a way to translate this into Python. So say:

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

which would return a list of:

["c", "d", "f"]

Is something like this possible?

How to test multiple variables against a single value? Answer#1:

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 0True 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 set to take advantage of the constant-cost membership test (i.e. in takes a fixed amount of time whatever the left-hand operand is).

Explanation

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 = 0x 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}.

How to test multiple variables against a single value? Answer#2:

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]]

How to test multiple variables against a single value? Answer#3:

As stated by Martijn Pieters, the correct, and fastest, the 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])

How to test multiple variables against a single value? Answer#4:

The direct way to write x or y or z == 0 is

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

But I don’t think, you like it. 🙂 And this way is ugly.

The other way (a better) is:

0 in (x, y, z)

BTW lots of ifs could be written as something like this

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break

How to test multiple variables against a single value? Answer#5:

If you ARE very very lazy, you can put the values inside an array. Such as

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

You can also put the numbers and letters in a dictionary and do it, but this is probably a LOT more complicated than simply if statements. That’s what you get for trying to be extra lazy 🙂

One more thing, your

if x or y or z == 0:

will compile, but not in the way you want it to. When you simply put a variable in an if statement (example)

if b

the program will check if the variable is not null. Another way to write the above statement (which makes more sense) is

if bool(b)

Bool is an inbuilt function in python which basically does the command of verifying a boolean statement (If you don’t know what that is, it is what you are trying to make in your if statement right now :))

Another lazy way I found is :

if any([x==0, y==0, z==0])

How to test multiple variables against a single value? Answer#6:

To check if a value is contained within a set of variables you can use the inbuilt modules itertools and operator.

For example:

Imports:

from itertools import repeat
from operator import contains

Declare variables:

x = 0
y = 1
z = 3

Create mapping of values (in the order you want to check):

check_values = (0, 1, 3)

Use itertools to allow repetition of the variables:

check_vars = repeat((x, y, z))

Finally, use the map function to create an iterator:

checker = map(contains, check_vars, check_values)

Then, when checking for the values (in the original order), use next():

if next(checker)  # Checks for 0
    # Do something
    pass
elif next(checker)  # Checks for 1
    # Do something
    pass

etc…

This has an advantage over the lambda x: x in (variables) because operator is an inbuilt module and is faster and more efficient than using lambda which has to create a custom in-place function.

Another option for checking if there is a non-zero (or False) value in a list:

not (x and y and z)

Equivalent:

not all((x, y, z))

Follow Programming Articles for more!

About ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ

Linux and Python enthusiast, in love with open source since 2014, Writer at programming-articles.com, India.

View all posts by ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ →