Posted on March 22, 2019· Updated on July 3, 2022

Python 列表推导式:分步入门指南 - Python 速查表

#python #basics
Image for Python 列表推导式:分步入门指南 - Python 速查表

列表推导式 (List Comprehensions) 是一种特殊的语法,它允许我们从其他列表中创建列表(维基百科Python 教程)。当处理数字以及一到两个嵌套的 for 循环 时,它们非常有用,但超出这个范围,它们可能会变得有点难以阅读。

在本文中,我们将创建一些 For 循环 并逐步将它们重写为 推导式 (Comprehensions)。

基础知识

事实上,列表推导式 并不复杂,但初次接触时仍然有点难以理解,因为它们看起来 有点 奇怪。为什么?嗯,它们书写的顺序与我们通常在 For 循环 中看到的顺序是相反的

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> for n in names:
...     print(n)
# Charles
# Susan
# Patrick
# George
# Carol

要使用 列表推导式 完成同样的事情,我们从 循环 的最末尾开始:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> [print(n) for n in names]
# Charles
# Susan
# Patrick
# George
# Carol

注意我们是如何颠倒顺序的:

  • 首先,我们有循环的输出内容 [print(n) ...]
  • 然后我们定义将存储每个元素并指向我们将要操作的 ListSetDictionary 的变量 [... for n in names]

使用推导式创建新列表

这是 列表推导式 的主要用途。其他用法可能会导致代码对您和其他人都难以阅读。

这是我们使用 For 循环 从现有集合创建新列表的方式:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

>>> new_list = []
>>> for n in names:
...     new_list.append(n)

>>> print(new_list)
# ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

这是使用 列表推导式 完成相同操作的方式:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> new_list = [n for n in names]
>>> print(new_list)
# ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

我们可以这样做的原因是 列表推导式 的标准行为是返回一个列表:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> [n for n in names]
# ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

添加条件判断

如果我们的 new_list 只包含以 C 开头的名字怎么办?使用 For 循环,我们会这样做:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

>>> new_list = []
>>> for n in names:
...     if n.startswith('C'):
...         new_list.append(n)

>>> print(new_list)
# ['Charles', 'Carol']

列表推导式 中,我们将 if 语句添加到其末尾:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> new_list = [n for n in names if n.startswith('C')]
>>> print(new_list)
# ['Charles', 'Carol']

可读性高得多。

格式化长列表推导式

这次,我们希望 new_list 不仅包含以 C 开头的名字,还包含以 e 结尾或包含 k 的名字:

>>> names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']
>>> new_list = [n for n in names if n.startswith('C') or n.endswith('e') or 'k' in n]
>>> print(new_list)
# ['Charles', 'Patrick', 'George', 'Carol']

这相当混乱。幸运的是,可以将 推导式 分成不同的行:

new_list = [
    n
    for n in names
    if n.startswith("C")
    or n.endswith("e")
    or "k" in n
]

集合和字典推导式

如果您学习了 列表推导式 的基础知识……恭喜!您刚刚用 集合字典 掌握了它。

集合推导式

>>> my_set = {"abc", "def"}

>>> # 在这里,我们使用 for 循环从一个新集合中创建大写元素
>>> new_set = set()
>>> for s in my_set:
...    new_set.add(s.upper())
>>> print(new_set)
# {'DEF', 'ABC'}

>>> # 同样的操作,但使用集合推导式
>>> new_set = {s.upper() for s in my_set}
>>> print(new_set)
# {'DEF', 'ABC'}

字典推导式

>>> my_dict = {'name': 'Christine', 'age': 98}

>>> # 使用 for 循环从现有字典创建新字典
>>> new_dict = {}
>>> for key, value in my_dict.items():
...     new_dict[key] = value
>>> print(new_dict)
# {'name': 'Christine', 'age': 98}

# 使用字典推导式
>>> new_dict = {key: value for key, value in my_dict.items()}  # 注意 ":"
>>> print(new_dict)
# {'name': 'Christine', 'age': 98}

推荐文章:Python 集合:是什么、为什么以及如何操作

结论

每当我学到新东西时,都会有一种立即使用它的冲动。当发生这种情况时,我强迫自己停下来思考片刻……我应该把这个庞大、嵌套且看起来已经很混乱的 For 循环 改成 列表推导式 吗?可能不应该。

可读性很重要。Python 之禅