3
if "aa" or "bb" or "cc" or "dd" or "ee" or "ff" in attrs["show"]:
    self.xx = xxxx

I have a code like this, to check if attrs["show"] contains either of these strings, then assign some value to self.xx

But is this "IF" command is correct? Because from my results, it seems like this if command is always true(which is impossible)

3 Answers 3

15

Try the following:

if any(s in attrs["show"] for s in ("aa", "bb", "cc", "dd", "ee", "ff")):
    self.xx = xxxx

Your current if statement will always evaluate to True, because instead of checking if each string is in attrs["show"] you are checking if "aa" is True, or if "bb" is True, and on and on. Since "aa" will always evaluate as True in a Boolean context, you will always enter the if clause.

Instead, use the any() function as in my example, which accepts an iterable and returns True if any of its elements are True. Similar to a bunch of or's as in your code, this will short-circuit as soon as it finds an element that is True. In this example, the above code is equivalent to the following (but much more concise!):

if ("aa" in attrs["show"] or "bb" in attrs["show"] or "cc" in attrs["show"] or
    "dd" in attrs["show"] or "ee" in attrs["show"] or "ff" in attrs["show"]):
    self.xx = xxxx
Sign up to request clarification or add additional context in comments.

2 Comments

A set would be more suited than a tuple for the list here, as on a set, membership is O(1) instead of O(n).
@Lattyware - No, actually changing it to a set wouldn't make a difference, because we are testing for the membership in attrs["show"] (which may already be a set), not in the tuple I define for looping over the strings. The only change is that you might check the strings in a different order.
4

In Python, and or evaluates to its first True operand (since True or'd with anything is True, Python doesn't need to look further than the first operand).

So:

"aa" or "bb" or "cc" or "dd" or "ee" or "ff" in attrs["show"]

... evaluates to:

"aa"

Which is True, because it's a non-empty string. The rest of the line is not even considered because it does not need to be.

So your if statement always executes because it is always True.

What you want is something like:

"aa" in attrs["show"] or "bb" in attrs["show"] or "cc" in attrs["show"] ...

This gets very wordy, so you can use any along with a generator expression to write it more succinctly.

any(s in attrs["show"] for s in ["aa", "bb", "cc", "dd", "ee", "ff"])

Comments

3

Your IF statement is not testing for anything. It WILL always evaluate as true, because of the way it is written.

You are asking python:

Is aa true
Is bb true
...

Python says 'Yes, "aa" is true, because its there!'

Correct your if statement or find a better way to find the values in the list:

any(x in ['aa','bb','cc','dd','ee','ff'] for x in attrs["show"])

11 Comments

Your first part is right. But if ("aa" or "bb" ...) in attrs["show"] is equivalent to if "aa" in attrs["show"], so is not what you intended.
Your "corrected" if statement always looks for "aa" in attrs["show"] and your second example is logically backward.
@rubik Would you mind clarifying? My posted answer is a solution based on as much information as the question poster gave. I cannot create more information than what was given.
@kindall Based on the question presented, my first example gives expected output. check if attrs["show"] contains either of these strings. First example will enter the if block if any of the values are in attrs["show"].
No, it does not. ("aa" or "bb" or "cc" or "dd" or "ee" or "ff") in attrs["show"] is the same as "aa" in attrs["show"].
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.