Sunday, 3 April 2016

python - How to test multiple variables against a value?



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?


Answer




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}.



No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...