列表解析为您提供写作的一种方式for
更简洁的循环。 当您要从现有列表或可迭代对象创建新列表时,它们可能很有用。 例如,您可以使用列表推导根据数字列表创建正方形列表。 同样,您也可以在数字列表上使用某些条件,以便您创建的新列表是原始列表的子集。
请记住,您不能将每个for
循环都编写for
列表理解。 还有一件事:“列表理解”这个名称可能有点令人困惑,因为这似乎表明该理解仅用于处理列表。 实际上,列表解析中的“列表”一词用于表示您可以循环使用Python中的任何可迭代项,而最终产品将是列表。
循环和列表理解
不使用任何条件的基本列表理解具有以下形式:
[<the_expression> for <the_element> in <the_iterable>]
让我们从编写一个非常基本的for
循环开始,以列出5的前15个倍数。首先,您需要创建一个空列表。 然后,您必须遍历一个数字范围,并将它们乘以5。新得到的数字序列将由5的倍数组成。
multiples = []
for n in range(1,16):
multiples.append(n*5)
print(multiples)
# [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]
上面的for
循环基本上具有以下结构:
for <the_element> in <the_iterable>:
<the_expression>
如果将其与先前阅读的列表理解形式进行比较,您会看到<the_element>
为n
, <the_iterable>
为range(1,16)
以及<the_expression>
为n*5
。 将这些值放在列表推导中将为我们提供以下结果:
multiples = [n*5 for n in range(1,15)]
multiples
# [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70]
类似地,您还可以获取一个包含给定数字的多维数据集的列表,如下所示:
cubes = [n**3 for n in range(1,16)]
print(cubes)
#[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728, 2197, 2744, 3375]
列表推导中的条件
您还可以使用if
条件从最终列表中过滤掉某些值。 在这种情况下,列表理解采用以下形式:
[<the_expression> for <the_element> in <the_iterable> if <the_condition>]
这种理解的一个基本示例是在给定范围内获得所有偶数。 执行此任务的for
循环如下所示:
evens = []
for n in range(1,21):
if n%2 == 0:
evens.append(n)
print(evens)
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
通过使用以下列表理解,也可以完成相同的操作:
evens = [n for n in range(1,21) if n%2 == 0]
print(evens)
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
使用列表推导的一个更复杂的示例是在其中添加.. if .. else ..
条件表达式。
在这种情况下, if
有条件, if
在列表理解中布置语句的顺序将与通常不同。 当您只有一个if
条件时,该条件将进入理解的结尾。 但是,在.. if .. else ..
表达式的情况下, for
循环的位置和条件表达式的位置会互换。 新订单为:
[<the_expression> if <the_condition> else <other_expression> for <the_element> in <the_iterable>]
让我们从编写详细的.. if .. else ..
条件表达式开始,以获得给定范围内的偶数平方和奇数立方。
squares_cubes = []
for n in range(1,16):
if n%2 == 0:
squares_cubes.append(n**2)
else:
squares_cubes.append(n**3)
print(squares_cubes)
# [1, 4, 27, 16, 125, 36, 343, 64, 729, 100, 1331, 144, 2197, 196, 3375]
上面的条件表达式具有以下结构:
for <the_element> in <the_iterable>:
if <the_condition>:
<the_expression>
else:
<other_expression>
将相应的值放在正确的位置将使您理解以下列表:
squares_cubes = [n**2 if n%2 == 0 else n**3 for n in range(1,16)]
print(squares_cubes)
# [1, 4, 27, 16, 125, 36, 343, 64, 729, 100, 1331, 144, 2197, 196, 3375]
嵌套循环的列表理解
您还可以在列表推导中使用嵌套循环。 可以在列表推导中放入的for
循环数没有限制。 但是,您必须记住,循环的顺序在原始代码和列表理解中应该相同。 您还可以在每个for
循环之后添加可选的if
条件。 嵌套有for
循环的列表理解将具有以下结构:
[ <the_expression> for <element_a> in <iterable_a> (optional if <condition_a>)
for <element_b> in <iterable_b> (optional if <condition_b>)
for <element_c> in <iterable_c> (optional if <condition_c>)
... and so on ...]
以下示例将使所有内容更加清晰。 有两个嵌套循环,将它们相乘即可得到乘法表。
multiplications = []
for i in range(1, 4):
for n in range(1, 11):
multiplications.append(i*n)
print(multiplications)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
这些嵌套的for
循环可以重写为:
for <element_a> in <iterable_a>:
for <element_b> in <iterable_b>:
<the_expression>
以这种形式编写循环后,将其转换为列表推导很容易:
multiplications = [i*n for i in range(1,4) for n in range(1,11)]
print(multiplications)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
您还可以使用类似编写的列表理解来平整列表列表。 外部的for
循环遍历各个列表,并将它们存储在变量row
。 然后,内部的for
循环将遍历当前row
中的所有元素。 在第一次迭代期间,变量row
的值为[1, 2, 3, 4]
。 第二个循环遍历此列表或row
,并将所有这些值附加到最终列表。
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
flatten = [n for row in matrix for n in row]
print(flatten)
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
嵌套列表推导
嵌套列表理解可能听起来与带有嵌套循环的列表理解相似,但是它们有很大的不同。 在第一种情况下,您正在处理循环内的循环。 在这种情况下,您将在列表推导中处理列表推导。 使用嵌套列表推导的一个很好的例子是为上一节创建矩阵的转置。
没有列表理解表达式,您将需要使用两个for
循环来创建转置。
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transpose = []
for i in range(4):
temp = []
for row in matrix:
temp.append(row[i])
transpose.append(temp)
print(transpose)
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
外循环遍历矩阵四次,因为其中有四列。 内部循环一次遍历当前行内的元素一个索引,并将其附加到称为temp
的临时列表中。 然后将temp
列表作为一行添加到转置矩阵中。 对于嵌套列表理解,最外层的循环位于末尾,而最内层的循环位于末尾。
下面是列表理解形式的上面的代码:
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transpose = [[row[n] for row in matrix] for n in range(4)]
print(transpose)
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
另一种解决方法是考虑列表理解的结构,该结构将取代您在本文开头了解的基本for
循环。
[<the_expression> for <the_element> in <the_iterable>]
如果将其与上面的嵌套列表理解进行比较,您会发现在这种情况下<the_expression>
实际上是另一个列表理解: [row[n] for row in matrix]
。 嵌套列表推导本身是基本的for
循环形式。
最后的想法
我希望本教程可以帮助您了解什么是列表推导,以及如何在基本的for
循环中使用它们来在创建列表时编写简洁且速度稍快的代码。
您应该记住的另一件事是代码的可读性。 为嵌套循环创建列表推导可能会使代码的可读性降低。 在这种情况下,您可以将列表理解分解为多行以提高可读性。
此外,不要犹豫,看看我们可以在Envato Market上出售和研究的东西 ,也不要犹豫,使用下面的提要来问任何问题并提供宝贵的反馈。
翻译自: https://code.tutsplus.com/tutorials/list-comprehensions-in-python--cms-26836