Python中的列表理解

列表解析为您提供写作的一种方式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

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值