不生成无用列表的列表推导等价写法

5 投票
4 回答
1964 浏览
提问于 2025-04-17 09:22

可能的重复问题:
用列表推导式仅仅为了副作用,这样做算不算Python风格?
列表推导式的正确用法 - Python

Python有一种既实用又优雅的列表推导式语法。不过据我所知,它总是会生成一个列表。有时候我会想用列表推导式,因为它简洁又好看,但其实我并不需要那个结果列表:

[some_func(x) for x in some_list if x>5]

some_func()可能会返回一些我不需要的东西,或者根本不返回任何东西。我试过用生成器语法:

(some_func(x) for x in some_list if x>5)

但你可能猜到,它并不会遍历some_list。它只在特定的情况下才会这样做:

other_func(some_func(x) for x in some_list if x>5)

那么...我是不是漏掉了什么语法,能让这个工作,还是说我总是得写三行代码呢?

for x in some_list:
    if x>5:
        some_func(x)

4 个回答

2

如果 some_func() 没有返回值(也就是说返回的是 None):

any(some_func(x) for x in some_list if x > 5)

这是一个可能的情况。

否则你可以这样做:

any(some_func(x) and False for x in some_list if x > 5)

或者,可能更容易理解(因为和 all 的普通英语意思相符)的是:

all(some_func(x) or True for x in some_list if x > 5)

不过,我更喜欢雷蒙德找到的 consume 方法,因为它不要求生成器返回特定的值来确保它被完全消耗,而且速度也会更快。

3

使用一个生成器表达式来获取合适的值,以便进行遍历。

for i in (x for x in some_list if x > 5):
    some_func(i)
10

我不知道你觉得这样是否优雅,但在itertools文档中有一个叫做 consume 的方法,它非常快,可以让一个迭代器运行到结束,而不需要先把所有结果放到一个列表里:

>>> consume(some_func(x) for x in some_list if x>5)

撰写回答