Testing Multiple String 'in' Conditions In List Comprehension
Solution 1:
You need to test each name explicitly if it's in n
:
[n for n in Names if ("Beatle" in n and ("Paul" in n or "Ringo" in n or "Yoko" in n))]
Otherwise the and
and or
use the truth value of you search strings (and each non-empty string is always True) and finally tests if Paul in n
(the first truth value of the or
s).
The documentation explicitly mentions this:
4.2. Boolean Operations — and, or, not
These are the Boolean operations, ordered by ascending priority:
Operation Result Notes x or y if x isfalse, then y, else x (1) x and y if x isfalse, then x, else y (2) not x if x isfalse, thenTrue, elseFalse (3)
Notes:
(1) This is a short-circuit operator, so it only evaluates the second argument if the first one is false.
(2) This is a short-circuit operator, so it only evaluates the second argument if the first one is true.
(3) not has a lower priority than non-Boolean operators, so not a == b is interpreted as not (a == b), and a == not b is a syntax error.
So "Beatle" and (...)
evaluates according to (2) to the second argument because "Beatle"
is truthy and according to (1) it evaluates to the first argument of the chained or
s: "Paul"
because it's also truthy.
Solution 2:
This doesn't do what you expect because the expression
("Paul" or "Ringo" or "Yoko")
evaluates to "Paul"
. Type it in at an interpreter prompt to confirm this.
And even that only seems to work because
("Beatle" and ("Paul" or "Ringo" or "Yoko"))
also evaluates to "Paul"
.
Solution 3:
The most straightforward solution is to just list
[n for n in Names if "Beatle" in n and ("Paul" in n or "Ringo" in n or "Yoko" in n)]
But you could use any
to get a bit closer to what you tried initially:
[n fornin Names if"Beatle"in n and any(x in n forxin ("Paul", "Ringo", "Yoko"))]
Post a Comment for "Testing Multiple String 'in' Conditions In List Comprehension"