仅仅为了副作用使用列表推导是否符合Python风格?

134 投票
7 回答
16779 浏览
提问于 2025-04-16 16:13

想象一下,我在调用一个函数时,主要是为了它的副作用,而不是它的返回值(比如在屏幕上打印、更新图形界面、写入文件等等)。

def fun_with_side_effects(x):
    ...side effects...
    return y

现在,使用列表推导式来调用这个函数,这样做算不算Pythonic呢:

[fun_with_side_effects(x) for x in y if (...conditions...)]

注意,我并没有把这个列表保存到任何地方

还是说我应该这样调用这个函数:

for x in y:
    if (...conditions...):
        fun_with_side_effects(x)

哪种方式更好,为什么呢?

7 个回答

30

列表推导式是用来创建列表的。如果你不是在创建列表,就不应该使用列表推导式。

所以我建议使用第二种方法,直接遍历列表,然后在符合条件的时候调用函数。

47

你不应该使用 列表 推导式,因为正如大家所说的那样,这样会创建一个你其实不需要的大临时列表。下面这两种方法是一样的:

consume(side_effects(x) for x in xs)

for x in xs:
    side_effects(x)

这里用的是 itertools 手册中的 consume 定义:

def consume(iterator, n=None):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

当然,后者更清晰,也更容易理解。

117

这样做是非常不符合Python编程风格的,任何有经验的Python程序员都会对此不满。中间生成的列表在创建后就被丢弃了,而且这个列表可能会非常大,因此创建它的成本也会很高。

撰写回答