4

why does print("Lorem" and "aliqua" in string ) Gives True. A Boolean,

But print("Lorem" or "aliqua" in string ) Gives 'Lorem'. A String

string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"

print("Lorem" and "aliqua" in string )
>>> True

print("Lorem" or "aliqua" in string )
>>> Lorem
  • You are dangerously close to the error: https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-for-equality-against-a-single-value – JonSG Jan 19 '22 at 15:28

4 Answers4

5

Try:

print("Lorem" in string and "aliqua" in string )

And

print("Lorem" in string or "aliqua" in string )

Explanation: The condition in string will always be true as it checks string is non empty.

>>> if "harsha":
...   print("hi")
...
hi
>>> if "":
...   print("hi")
...
<<No output>>
Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
4

In your second example, the string "Lorem" evaluates to True and is being printed without checking if "aliqua" appears. Try searching for both.

any([x in string for x in ["Lorem", "aliqua"]])
>> True
JDR
  • 107
  • 7
4

With boolean operations

x and y
x or y

The and operator returns the y if both x and y are both truthy. In your example y is "aliqua" in string which evaluates to True.

The or operator returns the x if x is truthy. In your example x is "Lorem".

See https://docs.python.org/3/reference/expressions.html#boolean-operations for more details.

If the goal is to check whether "Lorem" or "aliqua" occurs in string, realise that x or y in z is not (x or y) in z but x or (y in z). The solution is to use the in operator twice, e.g.

if (x in z) or (y in z):
    pass
freespace
  • 16,529
  • 4
  • 36
  • 58
2

Logical operators, lust like arithmetic ones, have relative precedence. * happens before +; in happens before and, which happens before or.

In your first case, in "Lorem" and "aliqua" in string, evaluation happens as if parenthesis were put like this "Lorem" and ("aliqua" in string). First "aliqua" in string evaluates to True, then "Lorem" and True evaluates to boolean True.

In your second case, in "Lorem" or "aliqua" in string evaluation order is the same: "Lorem" or ("aliqua" in string) -> "Lorem" or True -> "Lorem".

Now, however, we have to talk about one small optimization, that is used in many languages besides Python.

Logically speaking, expression True and A is fully equivalent to A (you can derive that mathematically). So, when Python sees that the first part of and is True (or true-ish) it just gives you the second argument. (In Python non-zeros, non-empty arrays/dictionaries, etc., are said to be "truthy", as in they give True when passed to bool(x)). Similarly with or — if it sees that we have something like "True-ish X and something" it just gives you back that X. Take a look:

In : True and "a"
Out: 'a'

In : "a" and True
Out: True

In : True or "a"
Out: True

In : "a" or True
Out: 'a'

That's why in your first case "Lorem" and True evaluates to True ("Lorem" is true-ish, so Python just gives back the second argument), while in the second case "Lorem" or True evaluates to "Lorem" (Python gives back the first argument).

If you want to check whether both substrings are in a string, you can construct a longer expression

"Lorem" in string and "aliqua" in strign

or use loops/arrays

string = "Lorem ipsum dolor sit ..."
words = ["Lorem", "ipsum", "dolor"]

# `all` checks whether everything is True
print(all(word in string for word in words))
# True

# `any` checks whether at least something is True
print(any(word in string for word in words))
# True
Physmatik
  • 256
  • 1
  • 6