Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?

If you've ever encountered the situation where your comparison statement, such as "a == x or y or z", always evaluates to True, then you're not alone. This is a common mistake that many newcomers to Python make. In this article, we'll dive into why this happens and explore the correct way to compare "a" to multiple values.

Understanding the Issue

Let's take a look at the code snippet you provided:


name = input("Hello. Please enter your name: ")
if name == "Kevin" or "Jon" or "Inbar":
    print("Access granted.")
else:
    print("Access denied.")
            

When you write "name == 'Kevin' or 'Jon' or 'Inbar'", you might expect that Python will evaluate each comparison separately. However, that's not how the "or" operator works in Python.

In Python, the "or" operator is a boolean operator, which requires two operands on each side to evaluate the expression. In this case, the left operand is "name == 'Kevin'", but what about the right operand? It turns out that Python treats non-empty strings as "True" in boolean expressions. So, when Python evaluates the expression "name == 'Kevin' or 'Jon' or 'Inbar'", it actually evaluates it as:

"(name == 'Kevin') or ('Jon') or ('Inbar')"

Since 'Jon' and 'Inbar' are non-empty strings and considered "True" in boolean expressions, the entire expression simplifies to:


if (name == 'Kevin') or True or True:
    print("Access granted.")
else:
    print("Access denied.")
            

As a result, the expression always evaluates to True, regardless of the value of "name". That is why unauthorized users are granted access.

The Correct Way to Compare "a" to Multiple Values

To compare "a" to multiple values, you need to explicitly write a separate comparison for each value. Here's how you can modify your code to do that:


name = input("Hello. Please enter your name: ")
if name == "Kevin" or name == "Jon" or name == "Inbar":
    print("Access granted.")
else:
    print("Access denied.")
            

By writing separate comparison statements for each value, we ensure that the comparison is evaluated correctly. Now, the expression "name == 'Kevin' or name == 'Jon' or name == 'Inbar'" will only evaluate to True if "name" is equal to any of those values.

Using a List or Set for Comparison

If you have a long list of values to compare "a" against, it can make your code messy and repetitive. In that case, you can use a list or set and the "in" operator to simplify your code.

Here's an example using a list:


name = input("Hello. Please enter your name: ")
authorized_users = ['Kevin', 'Jon', 'Inbar']

if name in authorized_users:
    print("Access granted.")
else:
    print("Access denied.")
            

By using the "in" operator, the code checks if the value of "name" is present in the "authorized_users" list. If it is, access is granted.

Alternatively, you can use a set for comparison, which can provide faster lookup times for large datasets:


name = input("Hello. Please enter your name: ")
authorized_users = {'Kevin', 'Jon', 'Inbar'}

if name in authorized_users:
    print("Access granted.")
else:
    print("Access denied.")
            

This code achieves the same result as the previous example, but with the use of a set instead of a list.

Conclusion

When comparing "a" to multiple values using the "or" operator, it's important to understand how the operator works in Python. By explicitly writing separate comparison statements or using a list/set with the "in" operator, you can accurately compare "a" to multiple values and avoid the common mistake of always evaluating to True.

Remember, the correct expression should be "a == x or a == y or a == z" or "a in [x, y, z]" for the desired result.