欢迎关注个人公众号:爱生活爱扣钉

在写 Python 代码的过程中,不论是新手还是老手大概都用过列表推导式。它们简洁、快速。我曾经几乎把它们当成万能工具:循环、过滤、数据转换,统统交给它。

但问题也随之而来。代码越来越难读,逻辑被压缩在一行行复杂的表达式里,调试简直是噩梦。直到某天,我终于决定停下来,换一种更清晰、可维护的写法。

为什么我不再沉迷于使用列表推导式

先说清楚:列表推导式并没有错。对于简单的操作,它们仍然是非常优雅的工具。比如:

result = [f(x) for x in data if x > 0 and isinstance(x, int)]

这种情况完全没问题。

可一旦逻辑变复杂,比如同时包含条件分支和过滤,情况就变得糟糕了:

result = [f(x) if x > 0 else g(x) for x in data if isinstance(x, int) and not is_ignored(x)]

这时,代码的可读性几乎坠落谷底。你写的已经不是“给人看的代码”,而是“写给解释器的谜题”。

三种替代方案

当逻辑复杂时,我更倾向于选择更清晰的写法。它们可能没有一行代码那么高级,但阅读、调试和维护的体验要好太多。

首先是 生成器函数。当逻辑需要多步处理时,生成器的 yield 显得格外优雅。

def transform_data(data):
    for x in data:
        if not isinstance(x, int) or is_ignored(x):
            continue
        yield f(x) if x > 0 else g(x)

result = list(transform_data(data))

这种写法一目了然,逻辑被清晰拆解出来,既省内存又容易调试。

其次是 map()filter() 的组合。配合具名函数使用时,它们表达力更强,还能在不同地方复用逻辑。

def is_valid(x):
    return isinstance(x, int) and not is_ignored(x)

def transform(x):
    return f(x) if x > 0 else g(x)

result = list(map(transform, filter(is_valid, data)))

最后,是很多人嫌弃“啰嗦”的 传统 for 循环。事实上,在复杂逻辑里,它们往往是最可读、最不容易出错的选择。

result = []
for x in data:
    if not isinstance(x, int) or is_ignored(x):
        continue
    if x > 0:
        result.append(f(x))
    else:
        result.append(g(x))

读起来毫无压力,团队协作时更是加分项。

关于性能

有人会说:列表推导式更快啊!

没错,它们确实在很多情况下比 for 循环快一些。但别忘了,大多数日常场景下,这种性能差距微乎其微。

相比之下,代码可读性和可维护性的重要性要高得多。除非你在写需要处理上百万数据的高性能核心模块,否则大可不必为那点性能纠结。

我仍然会用列表推导式的时候

当然,工具各有适用场景。我并没有完全抛弃列表推导式,只是更谨慎地使用它。

简单的转换:[x * 2 for x in numbers]

单一条件过滤:[x for x in items if x != '']

可控的嵌套场景,比如矩阵的扁平化。

前提是逻辑足够直观、能一眼看懂,那它依旧是我的首选。

一定记得代码是给人看的

过去,我总把写得短当成一种能力的证明。后来我发现,真正重要的是写得清楚

现在的我更关心:

  • 半年后再回头,能不能轻松读懂这段代码?
  • 同事能否快速理解逻辑?
  • 当需求变化时,能不能少踩坑、少出 bug?

如果你也习惯一行行列表推导式,不妨试试换个方式。下一次遇到复杂逻辑时,用生成器或者 for 循环重写一遍,然后退一步再读。

如果那一刻你觉得逻辑更清晰了,那就说明你升级了。写代码不是炫技,而是和未来的自己、和团队沟通。记住这句话:代码写给人看的,机器只是顺带执行。

最后修改:2025 年 10 月 30 日
本站福利|微信扫描二维码,永久享受 96 折充话费电费