python lambda list filtering with multiple conditions
--
Music by Eric Matyas
https://www.soundimage.org
Track title: The Builders
--
Chapters
00:00 Question
00:56 Accepted answer (Score 10)
01:14 Answer 2 (Score 7)
02:23 Answer 3 (Score 5)
03:15 Answer 4 (Score 3)
03:27 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".