0

I am trying to select certain strings in a list based on the existence of the words "foo" and "bar" or "baz" but I didn't manage to do it so far.

str_list = ['bar bar', 'foo foo', 'baz baz', 'bar foo', 'bar baz', 'foo baz']

for i in str_list:
    
    if "foo" and ("bar" or "baz") in i:
        
        print(i)

For the code above, I expected the output to be:

bar foo
foo baz

However, the output is:

bar bar
bar foo
bar baz

I tried this and it didn't work also:

    if "foo" in i and ("bar" or "baz") in i:
        
        print(i)

=======================================================

Solution:

for i in str_list:

    if "foo" in i and any(x in i for x in ["bar", "baz"]):

        print(i)
Output:
bar foo
foo baz
  • 3
    Does this answer your question? [How to test multiple variables against a value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-value) – Random Davis Dec 17 '20 at 18:42
  • 2
    `and` and `or` do *not* interact with comparison operators. They combine the *results* of individual comparisons. – chepner Dec 17 '20 at 18:47
  • 1
    @RandomDavis is headed in the right direction for what it seems like you're trying to accomplish. Something short and Pythonic like "if 'foo' in i and any((x in i for x in ('bar', 'baz'))) should do the trick. What "('bar' or 'baz') in i" evaluates to is "('bar' or 'baz')" ==> "(True or True)" since all strings that are not "" are Truthy in Python ==> "if (True) in i" ==> which is most certainly False. – Brendano257 Dec 17 '20 at 18:47
  • 1
    @Brendano257 The generator expression is more trouble than it's worth for only two comparisons. `'foo' in i and ('bar' in i or 'baz' in i)` – chepner Dec 17 '20 at 18:48
  • 1
    Your solution isn't a solution. `"bar" or "baz"` is equivalent to `"bar"`. You should replace `or` with a comma. – chepner Dec 17 '20 at 18:53
  • @chepner Certainly, but I went for it since foo/bar/baz is obviously not the intended use case, and some larger non-literal comparison could be done, though it's worth noting that ("bar", "baz") can and absolutely *should* be changed to a set if it's more than a few values. – Brendano257 Dec 17 '20 at 18:54

1 Answers1

1

The expression

"foo" and ("bar" or "baz") in i 

is evaluated like this:

  1. "bar" or "baz" gives always "bar"
  2. "bar" in i evaluates to true whenever bar is contained in i
  3. "foo" is a non empty string, which is always true
    1. and 3. are combined by and, thus true and 2. which means 3. is redundant

That explains what you see.

What you probably want is

if "foo" in i and ("bar" in i or "baz" in i)