我有一个列表,我想通过项目的属性进行筛选。

以下哪个是首选(可读性,性能,其他原因)?

xs = [x for x in xs if x.attribute == value]
xs = filter(lambda x: x.attribute == value, xs)

当前回答

就性能而言,这要视情况而定。

filter不返回一个列表而是一个迭代器,如果你需要列表“立即”过滤和列表转换,它比非常大的列表(>1M)的列表理解要慢40%左右。到100K的元素几乎没有区别,从600K开始就开始有区别了。

如果不转换为列表,筛选实际上是即时的。

更多信息请访问:https://blog.finxter.com/python-lists-filter-vs-list-comprehension-which-is-faster/

其他回答

我花了一些时间来熟悉高阶函数过滤器和映射。所以我习惯了他们,我实际上喜欢过滤器,因为它是明确的,它通过保持任何真实的过滤,我觉得很酷,我知道一些函数编程术语。

然后我读了这篇文章(Fluent Python Book):

映射和筛选函数仍然是内置的 在Python 3中,但是自从引入了列表推导式和generator ex‐ 压力没有那么重要。listcomp或genexp完成map和的工作 过滤器组合,但更可读。

现在我想,如果您可以使用已经广泛传播的习语(如列表推导)来实现它,那么为什么还要使用过滤器/映射的概念呢?此外,映射和过滤器是一种函数。在这种情况下,我更喜欢使用匿名函数lambdas。

最后,为了进行测试,我对两种方法(map和listComp)都进行了计时,我没有看到任何相关的速度差异,可以证明这是合理的。

from timeit import Timer

timeMap = Timer(lambda: list(map(lambda x: x*x, range(10**7))))
print(timeMap.timeit(number=100))

timeListComp = Timer(lambda:[(lambda x: x*x) for x in range(10**7)])
print(timeListComp.timeit(number=100))

#Map:                 166.95695265199174
#List Comprehension   177.97208347299602

我觉得第二种方法更容易读懂。它确切地告诉你目的是什么:过滤列表。 注意:不要使用list作为变量名

我会得出结论:使用列表理解而不是过滤器,因为它

更具可读性 更多的神谕的 更快(对于Python 3.11,参见附带的基准测试,也参见)

请记住,filter返回一个迭代器,而不是一个列表。

python3 -m timeit '[x for x in range(10000000) if x % 2 == 0]'            

1个循环,5个最佳:每循环270毫秒

python3 -m timeit 'list(filter(lambda x: x % 2 == 0, range(10000000)))'

1个循环,最好的5:432毫秒每循环

当我需要在列表理解之后过滤一些东西时,我使用了一小段。只是过滤器、lambda和列表的组合(或者称为猫的忠诚度和狗的清洁度)。

在这种情况下,我正在读取一个文件,剥离空行,注释掉行,以及在一行的注释之后的任何内容:

# Throw out blank lines and comments
with open('file.txt', 'r') as lines:        
    # From the inside out:
    #    [s.partition('#')[0].strip() for s in lines]... Throws out comments
    #   filter(lambda x: x!= '', [s.part... Filters out blank lines
    #  y for y in filter... Converts filter object to list
    file_contents = [y for y in filter(lambda x: x != '', [s.partition('#')[0].strip() for s in lines])]

你的问题既简单又有趣。它只是显示了python作为一种编程语言是多么的灵活。人们可以使用任何逻辑,根据自己的才能和理解来编写程序。只要我们得到答案就好。

在您的情况下,这只是一个简单的过滤方法,可以由两者完成,但我更喜欢第一个my_list = [x for x in my_list if x.attribute == value],因为它看起来简单,不需要任何特殊的语法。任何人都可以理解这个命令,并在需要时进行更改。 (虽然第二种方法也很简单,但对于初级程序员来说,它仍然比第一种方法更复杂)