列表推导式

Jinku Hu 2023年1月30日 2018年7月21日
  1. 列表推导式中的 else
  2. 双迭代
  3. 列表推导式中的空白符
列表推导式

Python 中的列表推导是非常简洁的语法结构,它通过将函数应用于列表中的每个元素,可用于从其他列表生成列表。以下部分解释并演示了这些表达式的用法。

列表推导通过施加一个表达式到的可迭代的每个元素来创建一个新的列表,最基本的形式是:

[ <expression> for <element> in <iterable> ]

还有一个可选的 if 条件:

[ <expression> for <element> in <iterable> if <condition> ]

如果(可选的)条件是真的话,那在迭代对象中的每个元素都会运行一遍表达式 <expression>。所有结果将在新列表中立即返回。Python 中的生成器表达式是懒惰地计算的,但是列表推导会立即施加到整个迭代器,它消耗与迭代器长度成比例的内存。

假如你要创建一个 list 平方整数:

squares = [x * x for x in (1, 2, 3, 4)]
# squares: [1, 4, 9, 16]

for 表达式一次设置 x(1, 2, 3, 4) 中的每个值。表达式的结果 x * x 附加到内部列表。完成后,内部列表将分配给变量 squares

除了一个速度增加(解释在这里),列表推导式大致相当于下面的 for 循环:

squares = []
for x in (1, 2, 3, 4):
    squares.append(x * x)
# squares: [1, 4, 9, 16]

列表推导式中的 else

else 可以在列表推导式中使用,但要注意其语法。if...else 判断是在 for 循环之前使用,而不是在以下之后:

# 创建一个含有 `apple` 的字符序列,替换其中的非元音字母为 `*`
# 比如 - 'apple' --> ['a', '*', '*', '*' ,'e']

[x for x in 'apple' if x in 'aeiou' else '*']
# SyntaxError: invalid syntax

# 使用 if/else 对时,它们应该在 for 的前面
[x if x in 'aeiou' else '*' for x in 'apple']
#['a', '*', '*', '*', 'e']

双迭代

双重迭代的顺序 [... for x in ... for y in ...] 是理解起来是自然或反直觉的。经验法则是遵循等效 for 循环:

def foo(i):
    return i + 0.5

for i in range(3):
    for x in foo(i):
        yield str(x)

这变为:

[str(x)
    for i in range(3)
        for x in foo(i)
]

这可以压缩成一行 [str(x)for i inrange(3)for x infoo(i)]

提示
跟一般的 for 双循环相比,只需要把最里层的表达式放在最前面写,就能够实现正确的列表表达式双迭代了。

列表推导式中的空白符

更复杂的列表推导可能需要很长的长度,这降低了代码的可读性,所以你可以增加空白字符或者换行来提高可读性,方便理解。

[
    x for x
    in 'foo'
    if x not in 'bar'
]
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn