列表推导式是我喜欢的 Python 特性之一。我非常喜爱列表推导式,为此我写过一篇关于它们的文章,做过一次针对它们的演讲,还在 PyCon 2018 上办过一个三小时推导式教程。
我喜爱推导式,但是我发现一旦一个新的 Python 使用者开始真正使用推导式,他们会在所有可能的地方用这些推导式。 推导式很可爱,但也很容易被滥用 。
Python资源共享群:484031800
这篇文章展示的案例中,从可读性的角度来看,推导式都不是完成任务的最佳工具。我们会讨论一些案例,它们有比使用推导式更具有可读性的选择,我们还会看到一些不明显的案例,它们根本就不需要使用推导式。
如果你还不是推导式的爱好者,那么这篇文章并不是为了吓退你,而是为了鼓励那些需要它的人(包括我)适度地使用它。
注意:本文中涉及到的“推导式”是涵盖了所有形式的推导式(列表,集合,字典)以及生成表达式。如果你对推导式还不是特别熟悉,我建议你先阅读这篇文章 或者这个演讲(这个演讲对生成器表达式挖掘的比较深)。
编写拥挤的推导式
列表推导式的批评者总是抱怨它们的可读性太差。他们是对的,很多推导式 都 很难读。 一些时候,让这些推导式变的更易读的方法仅仅是多一点间隔 。
观察一下这个函数中的推导式:
def get_factors(dividend):
"""返回所给数值的所有因子作为一个列表。"""
return [n for n in range(1, dividend+1) if dividend % n == 0]
复制代码
我们可以通过添加一些合适的换行来让这个推导式更易读:
def get_factors(dividend):
"""返回所给数值的所有因子作为一个列表。"""
return [
n
for n in range(1, dividend+1)
if dividend % n == 0
]
复制代码
代码越少意味着越好的可读性,但并不总是这样。 空白符是你的好朋友,尤其是在你使用推导式的时候 。
通常来说,我跟倾向于使用上面的缩进格式来写我的推导式并 利用多行来隔离代码 。有时我也用单行来写解析式,但是我不默认使用单行。
编写的推导式太丑
一些循环是 可以 被写成推导式的形式,但是如果循环里面有太多逻辑,那他们可能 不应该 被这样改写。
观察一下这个推导式:
fizzbuzz = [
f'fizzbuzz {n}' if n % 3 == 0 and n % 5 == 0
else f'fizz {n}' if n % 3 == 0
else f'buzz {n}' if n % 5 == 0
else n
for n in range(100)
]
复制代码
这个推导式等价于这样的 for 循环:
fizzbuzz = []
for n in range(100):
fizzbuzz.append(
f'fizzbuzz {n}' if n % 3 == 0 and n % 5 == 0
else f'fizz {n}' if n % 3 == 0
else f'buzz {n}' if n % 5 == 0
else n
)
复制代码
推导式和 for 循环都使用