Search code examples
pythonlogical-operatorsstring-comparison

How to compare strings with logical operators to a list of strings?


I'm looking for a way to compare 2 lists of strings. One list has logical operators in it like ["abc" or "def" and "ghi"]. I am looking for something simple to compare if "abc" or ("def" and "ghi") are in a list of strings like ["def", "ghi", "jlk"]. Both lists will be coming from a list or dictionary so they both need to be variables. I would like to do something like the following.

a = ["def", "ghi", "jlk"]
b = ["abc" or "def" and "ghi"]    

if b in a:
  print("True")
else:
  print("False")

I'm also having a hard time understanding why I can change some strings in my comparison and still get a match. The following returns True

a = ["abc", "def", "ghi", "jkl"]

if "abd" and "def" in a:
    print("True")

This returns False.

a = ["abc", "def", "ghi", "jkl"]

if "abc" and "dea" in a:
    print("True")

Solution

  • Despite being valid Python code, what you've written is semantically very far away from what you're trying to achieve. This is due to some incorrect assumptions about how the language behaves, or can be made to behave.

    First of all, your "list of logical operators" looks and behaves nothing like what you're expecting. This:

    ["abc" or "def" and "ghi"]
    

    Is a list literal, which will evaluate to a list containing a single string item thanks to short-circuit evaluation:

    ["abc"]
    

    The expression "abc" or "def" and "ghi" will evaluate down to a single object, in this case "abc". Non-empty strings are considered "truthy", and the binary or operator only needs one of its operands to be true/truthy in order for the whole expression to evaluate as true/truthy.

    Second, this:

    if "abd" and "def" in a:
    

    Must be parsed as:

    if ("abd") and ("def" in a):
    

    Again, when evaluated as a distinct boolean-expression, the string "abd" is non-empty, and therefore truthy. This is similar to saying:

    if True and "def" in a:
    

    or simply:

    if "def" in a:
    

    There are different ways to solve the issue, but perhaps the simplest solution you're looking for is:

    if ("abc" in a) or ("def" in a and "ghi" in a):
    

    Just because the code you've written reads like an English sentence to you, doesn't mean that this is how Python will interpret it.