了解Python3中的列表理解

来自菜鸟教程
跳转至:导航、​搜索

介绍

列表推导提供了一种基于现有列表创建列表的简洁方法。 使用列表推导时,可以利用任何 iterable 构建列表,包括 字符串元组

从语法上讲,列表推导由一个包含表达式的迭代组成,后跟一个 for 子句。 这之后可以附加额外的 forif 子句,因此熟悉 for 循环条件语句 将帮助您更好地理解列表推导。

列表推导式为创建列表和其他顺序 数据类型 提供了另一种语法。 虽然其他迭代方法(例如 for 循环)也可用于创建列表,但列表推导式可能是首选,因为它们可以限制程序中使用的行数。

先决条件

您应该在您的计算机或服务器上安装 Python 3 并设置编程环境。 如果您没有设置编程环境,您可以参考本地编程环境或服务器上的编程环境适合您的操作的安装和设置指南系统(Ubuntu、CentOS、Debian 等)

列出理解

在 Python 中,列表推导式的构造如下:

Info: 要跟随本教程中的示例代码,请通过运行 python3 命令在本地系统上打开 Python 交互式 shell。 然后,您可以通过在 >>> 提示符后添加示例来复制、粘贴或编辑示例。


list_variable = [x for x in iterable]

将列表或其他可迭代对象分配给变量。 代表可迭代项中的其他变量是围绕 for 子句构建的。 in 关键字在 for 循环中使用,以迭代 [X79X]。

让我们看一个基于字符串创建列表的示例:

shark_letters = [letter for letter in 'shark']
print(shark_letters)

在这里,新的列表被赋值给变量shark_lettersletter用来代替包含在可迭代字符串'shark'中的项。

为了让我们确认新列表 shark_letters 的样子,我们调用它到 print() 并接收以下输出:

Output['s', 'h', 'a', 'r', 'k']

我们使用列表推导式创建的列表由字符串 'shark' 中的项目组成,即每个字母对应一个字符串。

列表推导可以重写为 for 循环,但不是每个 for 循环都可以重写为列表推导。

使用我们在上面创建 shark_letters 列表的列表推导,让我们将其重写为 for 循环。 这可以帮助我们更好地理解列表理解是如何工作的。

shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)

当使用 for 循环创建列表时,分配给列表的变量需要使用空列表进行初始化,就像我们代码块的第一行一样。 然后 for 循环使用可迭代字符串 'shark' 中的变量 letter 对项目进行迭代。 在 for 循环中,字符串中的每个项目都使用 list.append(x) 方法 添加到列表中

将列表推导重写为 for 循环为我们提供了相同的输出:

Output['s', 'h', 'a', 'r', 'k']

列表推导可以重写为 for 循环,并且一些 for 循环可以重写为列表推导以使代码更简洁。

将条件与列表推导结合使用

列表推导可以在创建新列表时利用条件语句来修改现有列表或其他顺序数据类型。

让我们看一个在列表推导中使用的 if 语句的示例:

fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)

列表推导使用元组 fish_tuple 作为名为 fish_list 的新列表的基础。 使用 forin 的关键字,就像它们在 上面的 部分中一样,现在添加了 if 语句。 if 语句表示只添加那些与字符串 'octopus' 不等价的项目,因此新列表仅从元组中获取不匹配 'octopus' 的项目。

当我们运行它时,我们会注意到 fish_list 包含与 fish_tuple 相同的字符串项,除了字符串 'octopus' 已被省略:

Output['blowfish', 'clownfish', 'catfish']

因此,我们的新列表包含原始元组的所有项目,但条件语句排除的字符串除外。

我们将创建另一个使用 数学运算符整数range() 序列类型 的示例。

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

正在创建的列表 number_list 将填充 0-9 如果 项目的值可被 2 整除的每个项目的平方值。 输出如下:

Output[0, 4, 16, 36, 64]

为了进一步分解列表推导的作用,让我们考虑一下如果我们只调用 x for x in range(10) 会打印出什么。 我们的小程序和输出将如下所示:

number_list = [x for x in range(10)]
print(number_list)
Output[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

现在,让我们添加条件语句:

number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
Output[0, 2, 4, 6, 8]

if 语句将最终列表中的项目限制为仅包括那些可以被 2 整除的项目,省略所有奇数。

最后,我们可以添加运算符以使每个 x 平方:

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

因此,上一个 [0, 2, 4, 6, 8] 列表中的每个数字现在都是平方的:

Output[0, 4, 16, 36, 64]

您还可以使用列表推导复制 嵌套的 if 语句

number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)

在这里,列表推导将首先检查数字 x 是否能被 3 整除,然后检查 x 是否能被 5 整除。 如果 x 满足这两个要求,它将打印,输出为:

Output[0, 15, 30, 45, 60, 75, 90]

条件 if 语句可用于控制现有序列中的哪些项目包含在新列表的创建中。

列表理解中的嵌套循环

嵌套循环可用于在我们的程序中执行多次迭代。

这一次,我们将回顾一个现有的嵌套 for 循环结构,并朝着列表理解的方向努力。

我们的代码将创建一个新列表,该列表迭代 2 个列表并基于它们执行数学运算。 这是我们嵌套的 for 循环代码块:

my_list = []

for x in [20, 40, 60]:
    for y in [2, 4, 6]:
        my_list.append(x * y)

print(my_list)

当我们运行此代码时,我们会收到以下输出:

Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

此代码在每次迭代中将第一个列表中的项目乘以第二个列表中的项目。

要将其转换为列表推导式,我们将从 x * y 操作开始将每一行代码压缩为一行。 接下来是外部 for 循环,然后是内部 for 循环。 我们将在列表解析下方添加一个 print() 语句,以确认新列表与我们使用上面嵌套的 for 循环块创建的列表匹配:

my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

我们的列表理解采用嵌套的 for 循环并将它们展平为一行代码,同时仍然创建完全相同的列表以分配给 my_list 变量。

列表推导式为我们提供了一种简洁的制作列表的方式,使我们能够将几行代码提炼成一行。 然而,值得记住的是,我们的代码的可读性应该总是优先考虑的,所以当列表理解行变得太长或笨拙时,最好将它分成循环。

结论

列表推导允许我们将一个列表或其他序列转换为一个新列表。 它们为完成这项任务提供了简洁的语法,限制了我们的代码行数。

列表推导遵循集合构建符号或集合推导的数学形式,因此对于具有数学背景的程序员来说,它们可能特别直观。

尽管列表推导可以使我们的代码更简洁,但确保我们的最终代码尽可能具有可读性很重要,因此应避免使用非常长的单行代码以确保我们的代码对用户友好。