2016-07-14 4 views
2

Ma compréhension sur les listes de filtrage avec lambda est que le filtre renverra tous les éléments de la liste qui retournent True pour la fonction lambda. Dans ce cas, le code suivant,python lambda liste filtrage avec plusieurs conditions

inputlist = [] 
inputlist.append(["1", "2", "3", "a"]) 
inputlist.append(["4", "5", "6", "b"]) 
inputlist.append(["1", "2", "4", "c"]) 
inputlist.append(["4", "5", "7", "d"]) 

outputlist = filter(lambda x: (x[0] != "1" and x[1] != "2" and x[2] != "3"), inputlist) 
for item in outputlist: print(item) 

La sortie doit être

['4', '5', '6', 'b'] 
['1', '2', '4', 'c'] 
['4', '5', '7', 'd'] 

Mais la sortie que je reçois est

['4', '5', '6', 'b'] 
['4', '5', '7', 'd'] 

je reçois le résultat attendu, si je l'utilise

outputlist = filter(lambda x: (x[0] != "1" or x[1] != "2" or x[2] != "3"), inputlist) 

Que puis-je faire? ng idiot ici? Ou est-ce que ma compréhension n'est pas correcte?

+0

Nous ne pouvons pas dire si votre compréhension est correcte, parce que vous ne nous avez pas dit ce que vous attendez de la fonction 'lambda'. Si vous joignez les conditions avec 'and', il ne sera pas évalué à' true', sauf si toutes les conditions sont vraies. Si vous joignez les conditions avec 'or', il évaluera' true' si seulement l'une des conditions est vraie. –

+0

Maintenant je me sens vraiment bête! Je pense que je dois arrêter de travailler et frapper le sac. Désolé de perdre votre temps les gars. – user3300676

Répondre

4

x = ['1', '2', '4', 'c'], donc x[1]=='2', ce qui fait que l'expression (x[0] != "1" and x[1] != "2" and x[2] != "3") soit évaluée comme False.

Lorsque les conditions sont réunies par and, ils reviennent True que si toutes les conditions sont True, et s'ils sont rejoints par or, ils reviennent True lorsque le premier d'entre eux est évalué à True.

2

Eh bien, ['1', '2', '4', 'c'] ne satisfait pas la condition que x[0] != "1", ni ne satisfait à la condition que x[1] != "2".

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

ne réussit pas à l'état

x[0] != "1" 

ainsi que

x[1] != "2" 

Au lieu d'utiliser or, je crois que la façon plus naturelle et facile à lire est:

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

Out de curiosité, J'ai comparé trois méthodes de, euh ... de comparaison, et les résultats étaient comme prévu: les listes de découpage étaient les plus lentes, l'utilisation de tuples était plus rapide, et l'utilisation d'opérateurs booléens était la plus rapide. Plus précisément, les trois approches comparées ont été

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 

Et les résultats, respectivement:

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.2399928924, 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] 
+1

Si vous utilisez une liste sur le côté droit de '! =', Vous pouvez alors utiliser une tranche sur le côté gauche 'x [: 3]! = [" 1 "," 2 "," 3 "]' – Blckknght

+0

@Blckknght True. –

2

Le filtre agit exactement comme il se doit. Dans le premier cas

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

le seul filtre « accepte » les listes dont le premier élément est pas 1 et dont la deuxième élément n'est pas 2 ET dont le troisième élément n'est pas 3. Ainsi, la liste ['1', '2', '4', 'c'] ne le fera pas à travers parce que son premier élément est 1. au contraire,

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

acceptera une liste dont le premier élément est pas 1 ou dont le second élément n'est pas 2 ou dont le troisième élément n'est pas 3.Ainsi, ['1', '2', '4', 'c'] sera accepté car son troisième élément n'est pas 3.