跳到主要内容

Python 列表推导

提示

1.列表推导和for循环的对比:列表推导提供了一种简洁的方式来创建列表,相比于传统的for循环更加简洁高效。例如,使用[letter for letter in 'human']可以轻松创建一个由字符串 'human' 字母组成的列表。

2.列表推导的语法:列表推导的基本语法是[expression for item in list],可以用于快速处理和修改列表中的元素。这种方法不仅适用于列表,也适用于字符串和元组。

3.列表推导中的条件语句:列表推导支持包含条件语句,例如[x for x in range(20) if x % 2 == 0],这可以选择性地对列表中的元素进行操作。此外,列表推导还可以嵌套使用,以实现更复杂的数据处理。

列表推导 vs Python 中的 For 循环

假设我们想要分离单词 human 的字母,并将这些字母作为列表的元素。首先想到的可能是使用for 循环

示例 1:使用 for 循环遍历字符串

h_letters = []

for letter in 'human':
h_letters.append(letter)

print(h_letters)

当我们运行程序时,输出将是:

['h', 'u', 'm', 'a', 'n']

然而,Python 有一种更简便的方法来解决这个问题,即使用列表推导。列表推导是一种基于现有列表定义和创建列表的优雅方式。

让我们看看如何使用列表推导重写上述程序。

示例 2:使用列表推导遍历字符串

h_letters = [ letter for letter in 'human' ]
print(h_letters)

当我们运行程序时,输出将是:

['h', 'u', 'm', 'a', 'n']

在上述示例中,一个新列表被赋值给变量 h_letters,这个列表包含了可迭代字符串 'human' 的元素。我们调用 print() 函数来获取输出。

列表推导的语法

[expression for item in list]

列表推导语法分解

我们现在可以识别出哪里使用了列表推导。

如果您注意到,human 是一个字符串,而不是列表。这就是列表推导的力量。它能识别它接收到的是字符串还是元组,并像处理列表一样处理它们。

您可以使用循环来实现这一点。然而,并非每个循环都可以重写为列表推导。但随着您学习和熟悉列表推导,您会发现自己用这种优雅的语法替换了越来越多的循环。

列表推导 vs Lambda 函数

列表推导并不是处理列表的唯一方式。各种内置函数和 lambda 函数 可以用更少的代码行来创建和修改列表。

示例 3:在列表中使用 Lambda 函数

letters = list(map(lambda x: x, 'human'))
print(letters)

当我们运行程序时,输出将是

['h','u','m','a','n']

然而,列表推导通常比 lambda 函数更易于人类阅读。使用列表推导时,更容易理解程序员想要实现的目标。

列表推导中的条件语句

列表推导可以利用条件语句来修改现有列表(或其他元组)。我们将创建一个使用数学运算符、整数和 range() 的列表。

示例 4:使用 if 与列表推导

number_list = [ x for x in range(20) if x % 2 == 0]
print(number_list)

当我们运行上述程序时,输出将是:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

列表 number_list 将由 0-19 范围内的元素填充,如果该元素的值可以被 2 整除。

示例 5:嵌套 IF 与列表推导

num_list = [y for y in range(100) if y % 2 == 0 if y % 5 == 0]
print(num_list)

当我们运行上述程序时,输出将是:

[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

在这里,列表推导会检查:

  1. y 是否能被 2 整除?
  2. y 是否能被 5 整除?

如果 y 满足这两个条件,y 将被添加到 num_list 中。

示例 6:在列表推导中使用 if...else

obj = ["Even" if i%2==0 else "Odd" for i in range(10)]
print(obj)

当我们运行上述程序时,输出将会是:

['Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd']

这里,列表推导会检查从 0 到 9 的 10 个数字。如果 i 能被 2 整除,则 Even 会被添加到 obj 列表中。如果不能,则添加 Odd

嵌套循环在列表推导中的应用

假设我们需要计算矩阵的转置,这需要嵌套的 for 循环。让我们先看看如何使用普通 for 循环来做。

示例 7:使用嵌套循环进行矩阵转置

transposed = []
matrix = [[1, 2, 3, 4], [4, 5, 6, 8]]

for i in range(len(matrix[0])):
transposed_row = []

for row in matrix:
transposed_row.append(row[i])
transposed.append(transposed_row)

print(transposed)

输出

[[1, 4], [2, 5], [3, 6], [4, 8]]

上述代码使用两个 for 循环来找出矩阵的转置。

我们也可以在列表推导中执行嵌套迭代。在这一节中,我们将使用列表推导中的嵌套循环来找出矩阵的转置。

示例 8:使用列表推导进行矩阵转置

matrix = [[1, 2], [3, 4], [5, 6], [7, 8]]
transpose = [[row[i] for row in matrix] for i in range(2)]
print (transpose)

当我们运行上述程序时,输出将会是:

[[1, 3, 5, 7], [2, 4, 6, 8]]

在上述程序中,我们有一个变量 matrix,它有 4 行和 2 列。我们需要找出矩阵的转置。为此,我们使用了列表推导。

注意: 列表推导中的嵌套循环并不像普通的嵌套循环那样工作。在上述程序中,for i in range(2)row[i] for row in matrix 之前执行。因此,首先为 i 分配一个值,然后由 row[i] 指向的元素被添加到 transpose 变量中。

需要记住的关键点

  • 列表推导是一种优雅的方式,基于现有列表定义和创建列表。
  • 通常,列表推导比普通函数和循环更紧凑、更快地创建列表。
  • 然而,我们应该避免在一行中编写非常长的列表推导,以确保代码的易用性。
  • 记住,每个列表推导都可以用 for 循环重写,但并不是每个 for 循环都可以用列表推导的形式重写。