多条件python lambda列表过滤

2024-10-05 12:38:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我对使用lambda筛选列表的理解是,该筛选器将返回列表中所有返回lambda函数True的元素。在这种情况下,对于下面的代码

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)

输出应该是

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

但我得到的结果是

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

如果我使用

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

我在这里干嘛这么傻?还是我的理解不正确?


Tags: orandlambda函数代码true元素列表
3条回答

过滤器的作用和它应该的完全一样。在第一种情况下

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

过滤器只“接受”第一个元素不是1、第二个元素不是2、第三个元素不是3的列表。因此列表['1', '2', '4', 'c']将无法通过,因为它的第一个元素是1。恰恰相反

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

将接受第一个元素不是1或第二个元素不是2或第三个元素不是3的任何列表。因此,['1', '2', '4', 'c']将被接受,因为它的第三个元素不是3。

x = ['1', '2', '4', 'c'],所以x[1]=='2',这使得表达式(x[0] != "1" and x[1] != "2" and x[2] != "3")被计算为False

当条件由and连接时,只有当所有条件都是True时,它们才返回True;如果条件由or连接,则当其中第一个条件被计算为True时,它们才返回True

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

不符合条件

x[0] != "1"

以及

x[1] != "2"

与其使用or,我相信更自然和可读的方法是:

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

出于好奇,我比较了三种方法,呃。。。比较,结果如预期:切片列表最慢,使用元组更快,使用布尔运算符最快。更准确地说,比较的三种方法是

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

结果分别是:

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]

相关问题 更多 >

    热门问题