The Python Oracle

python lambda list filtering with multiple conditions

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 2 Looping

--

Chapters
00:00 Python Lambda List Filtering With Multiple Conditions
00:44 Answer 1 Score 3
00:49 Accepted Answer Score 10
01:05 Answer 3 Score 7
01:59 Answer 4 Score 5
02:37 Thank you

--

Full question
https://stackoverflow.com/questions/3836...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #list #lambda #filter #multipleconditions

#avk47



ACCEPTED ANSWER

Score 10


x = ['1', '2', '4', 'c'], so x[1]=='2', which makes the expression (x[0] != "1" and x[1] != "2" and x[2] != "3") be evaluated as False.

When conditions are joined by and, they return True only if all conditions are True, and if they are joined by or, they return True when the first among them is evaluated to be True.




ANSWER 2

Score 7


['1', '2', '4', 'c']

Fails for condition

x[0] != "1"

as well as

x[1] != "2"

Instead of using or, I believe the more natural and readable way is:

lambda x: (x[0], x[1], x[2]) != ('1','2','3')

Out of curiosity, I compared three methods of, er... comparing, and the results were as expected: slicing lists was the slowest, using tuples was faster, and using boolean operators was the fastest. More precisely, the three approaches compared were

list_slice_compare = lambda x: x[:3] != [1,2,3]

tuple_compare = lambda x: (x[0],x[1],x[2]) != (1,2,3)

bool_op_compare = lambda x: x[0]!= 1 or x[1] != 2 or x[2]!= 3

And the results, respectively:

In [30]: timeit.Timer(setup="import timeit,random; rand_list = [random.randint(1,9) for _ in range(4)]; list_slice_compare = lambda x: x[:3] != [1,2,3]", stmt="list_slice_compare(rand_list)").repeat()
Out[30]: [0.3207617177499742, 0.3230015148823213, 0.31987868894918847]

In [31]: timeit.Timer(setup="import timeit,random; rand_list = [random.randint(1,9) for _ in range(4)]; tuple_compare = lambda x: (x[0],x[1],x[2]) != (1,2,3)", stmt="tuple_compare(rand_list)").repeat()
Out[31]: [0.2399928924012329, 0.23692036176475995, 0.2369164465619633]

In [32]: timeit.Timer(setup="import timeit,random; rand_list = [random.randint(1,9) for _ in range(4)]; bool_op_compare = lambda x: x[0]!= 1 or x[1] != 2 or x[2]!= 3", stmt="bool_op_compare(rand_list)").repeat()
Out[32]: [0.144389363900018, 0.1452672728203197, 0.1431527621755322]



ANSWER 3

Score 5


The filter is acting exactly like it should. In the first case

lambda x: (x[0] != "1" and x[1] != "2" and x[2] != "3")

the filter only "accepts" lists whose first element is not 1 AND whose second element is not 2 AND whose third element is not 3. Thus the list ['1', '2', '4', 'c'] will not make it through because its first element is 1. On the contrary,

lambda x: (x[0] != "1" or x[1] != "2" or x[2] != "3")

will accept any list whose first element is not 1 or whose second element is not 2 or whose third element is not 3. Thus, ['1', '2', '4', 'c'] will be accepted because its third element is not 3.




ANSWER 4

Score 3


Well, ['1', '2', '4', 'c'] doesn't satisfy the condition that x[0] != "1", nor does it satisfy the condition that x[1] != "2".