Python 列表推导式与生成器表达式

2024 年 8 月 29 日 | 4 分钟阅读

在本教程中,我们将讨论列表推导式和生成器表达式之间的一些重要区别。它们的语法非常相似,但它们有一些显著的差异。让我们简要介绍一下列表推导式和生成器表达式。

什么是列表推导式?

列表推导式是一种创建列表的绝佳方式。它允许我们使用循环和条件语句来创建列表。我们可以用更少的代码完成任务。正常的列表需要 3-4 行代码,而列表推导式可以在一行内完成。让我们理解下面的代码。

示例 -

输出

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

我们可以用列表推导式在一行代码中完成同样的事情。

示例 -

输出

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

正如我们所见,列表推导式的语法包含了 for 循环和 if 条件。我们也可以使用嵌套的 for 循环,但这会降低可读性。

让我们看另一个例子。

示例 - 使用普通列表

输出

square_cube = [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]

示例 - 使用列表推导式

输出

With List Comprehension = [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]

这两个代码做的事情是相同的,根据条件 num%2 ==0 过滤数字,并相应地执行 square_cube.append(num**2)square_cube.append(num**3)

什么是生成器表达式?

生成器表达式类似于列表推导式,但它使用圆括号 () 和方括号 []。与列表不同,它返回一个生成器对象。生成器不会将整个序列保存在内存中,而是在需要时生成下一个元素。普通函数在调用 return 语句时终止。但生成器函数使用 yield 语句,它会保存函数的当前状态,并在下次调用函数时从同一状态恢复。

生成器表达式提供了一种无需使用 yield 关键字即可创建生成器的方式。

让我们理解下面的例子。

示例 -

输出

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

示例 - 生成器表达式

输出

<generator object <genexpr> at 0x7fa0e3f3b580>

上面的代码返回一个生成器对象;要打印表达式的值,我们需要迭代生成器对象。

输出

0
2
4
6
8
10
12
14
16
18

在这里我们获得了所有元素。现在我们来看看生成器表达式和列表推导式之间的区别。

生成器表达式与列表推导式之间的区别

两者的语法都非常相似,唯一的区别在于列表推导式用方括号括起来,而生成器表达式用圆括号括起来。

生成器按需生成元素,这意味着它只计算需要的值。而普通函数在遇到 return 语句时就终止了,Python 则会为整个列表保留内存。

生成器表达式相比列表的主要优势是内存效率。生成器表达式比列表更节省内存。让我们通过以下示例来理解。

示例 -

输出

在创建列表时,我们可以看到区别,Python 会为整个列表预留内存并计算它将消耗的总内存。而生成器表达式则按需生成序列的下一个元素。它计算下一个值所需的内存。

生成器速度较慢,因为序列的元素每次都需要计算和生成。为了生成下次的值,函数的当前状态必须被保存。

示例 -

输出

14.614160199999986

示例 -

输出

0.9265093000000206

正如我们所见,执行时间存在显著差异。生成器表达式比列表推导式快得多,并且更节省时间。

结论

本教程包括了列表推导式和生成器表达式的基本介绍。我们还学习了它们之间的一些重要区别。列表推导式有效地减少了代码行数,而生成器表达式则按需生成值。有些人认为推导式是更 Pythonic 的编码方式。选择哪种方式最适合您,由您决定。