简介
列表推导式 提供了一种简洁的方式来基于现有列表创建新列表。使用列表推导式时,可以利用任何可迭代对象,包括字符串和元组。
在语法上,列表推导式由包含表达式的可迭代对象后跟一个 for
子句组成。这之后可以跟随额外的 for
或 if
子句,因此熟悉 for 循环 和 条件语句 将有助于更好地理解列表推导式。
列表推导式提供了创建列表和其他顺序数据类型的替代语法。虽然其他迭代方法,比如 for
循环,也可以用来创建列表,但列表推导式可能更受青睐,因为它们可以限制程序中使用的行数。
列表推导式
在 Python 中,列表推导式的构造方式如下:
list_variable = [x for x in iterable]
一个列表或其他可迭代对象被赋值给一个变量。围绕 for
子句构造了用于表示可迭代对象中的项的额外变量。使用 in
关键字,就像在 for
循环中一样,来迭代可迭代对象。
让我们看一个基于字符串创建列表的示例:
shark_letters = [letter for letter in 'shark']
print(shark_letters)
在这里,新列表被赋值给变量 shark_letters
,并且 letter
被用来代表可迭代字符串 'shark'
中的项。
为了确认新列表 shark_letters
的样子,我们调用 print()
来接收以下输出:
['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
循环后,我们得到相同的输出:
['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
的基础。使用了 for
和 in
关键字,就像上面的部分一样,现在添加了一个 if
语句。if
语句表示只添加那些不等于字符串 'octopus'
的项,因此新列表只接收来自元组的不匹配 'octopus'
的项。
当我们运行这段代码时,我们会注意到 fish_list
包含与 fish_tuple
相同的字符串项,除了字符串 'octopus'
被省略了:
['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 整除。输出如下:
[0, 4, 16, 36, 64]
为了更详细地解释列表推导式的工作原理,让我们考虑如果我们只调用 x for x in range(10)
会打印出什么。我们的小程序和输出将如下所示:
number_list = [x for x in range(10)]
print(number_list)
[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)
[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]
现在都被平方:
[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
满足这两个条件,它将被打印,输出为:
[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)
当我们运行这段代码时,我们会得到以下输出:
[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)
[40, 80, 120, 80, 160, 240, 120, 240, 360]
我们的列表推导式将嵌套的 for
循环压缩为一行代码,同时仍然创建与分配给 my_list
变量的完全相同的列表。
列表推导式为我们提供了一种简洁的方式来创建列表,使我们能够将几行代码压缩为一行。然而,值得记住的是,我们的代码的可读性应始终优先考虑,因此当列表推导式变得过长或难以处理时,最好将其拆分为循环。
结论
列表推导式允许我们将一个列表或其他序列转换为新列表。它们为完成此任务提供了一种简洁的语法,限制了我们的代码行数。
列表推导式遵循集合构建符号或集合推导式的数学形式,因此对于具有数学背景的程序员来说可能特别直观。
尽管列表推导式可以使我们的代码更加简洁,但重要的是确保我们的最终代码尽可能可读,因此应避免非常长的单行代码,以确保我们的代码用户友好。