1

Say I have a Pandas Dataframe with 1 column called contracting_department. It has 3 rows of data:

  1. fire dept. development
  2. park development
  3. police development

I am seeing something weird with the parentheses

Scenario 1:

df["contracting_department"] = df["contracting_department"].str.lower()
for i in df.contracting_department:
    if ("fire" or "police") in i : 
        print("IN")
    else:
        print("NOT IN")

output:

  1. IN
  2. NOT IN
  3. NOT IN

Obviously this is wrong and should be IN, NOT IN, IN.

Scenario 2:

df["contracting_department"] = df["contracting_department"].str.lower()
for i in df.contracting_department:
    if "fire" or "police" in i : 
        print("IN")
    else:
        print("NOT IN")

Output2:

  1. IN
  2. IN
  3. IN

Any idea what is happening here?

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • 1
    `("fire" or "police")` evaluates to just `"fire"`, because it's the first thing that's truthy, and *that's how a boolean-logic short-circuiting `or` works*. – Charles Duffy May 20 '20 at 15:13
  • And `"fire" or "police" in i` *likewise* evaluates to just `"fire"`, so whether `police in i` is true is never tested at all. Think of it as `("fire") or ("police" in i)`; that's **not at all the same** as `("fire" in i) or ("police" in i)`. – Charles Duffy May 20 '20 at 15:13
  • And the `if "fire"` is always true. Strings are always truthy if they're non-empty. – ggorlen May 20 '20 at 15:14
  • 1
    `if "fire" or "police" in i` is the wrong way to check multiple values. See https://stackoverflow.com/q/15112125/494134 – John Gordon May 20 '20 at 15:15
  • @JohnGordon what is the best way to check for multiple values within a string? – user_1960_02 May 20 '20 at 15:17
  • @user_1960_02, the linked duplicates describe that. See the *This question already has answers here:* section up by the top. (Insofar as the OP there gets is using `and` rather than `or`, note that the relevant equivalent to Python's `all` is `any`). – Charles Duffy May 20 '20 at 15:17
  • `if "fire" in i or "police" in i:` – John Gordon May 20 '20 at 15:26
  • Or if you have lots of values, `if any(s in i for s in ["fire", "police", ...])` – Samwise May 20 '20 at 15:32

1 Answers1

1
if ("fire" or "police") in i

translates to:

if "fire" in i

since the value of ("fire" or "police") is "fire" (the or operator returns the left side if it's truthy, else the right side).

if "fire" or "police" in i

translates to:

if ("fire") or ("police" in i)

which is just:

if True

since "fire" is truthy. It doesn't matter if "police" is in i since "fire" will always make the condition true.

Samwise
  • 68,105
  • 3
  • 30
  • 44