繁体   English   中英

python列表理解加倍

[英]python list comprehension double for

vec = [[1,2,3], [4,5,6], [7,8,9]]
print [num for elem in vec for num in elem]      <----- this

>>> [1, 2, 3, 4, 5, 6, 7, 8, 9]

这是在欺骗我。
我知道 elem 是来自for elem in vic的列表中的列表
我不太明白numfor num in elem的开头和结尾的用法。

python如何解释这个?
它查看的顺序是什么?

让我们分解它。

一个简单的列表理解:

[x for x in collection]

如果我们把它分成几部分,这很容易理解: [A for B in C]

  • A是将在结果列表中的项目
  • B是集合C中的每一项
  • C是集合本身。

这样,可以写:

[x.lower() for x in words]

为了将列表中的所有单词转换为小写。


当我们用另一个列表将其复杂化时,如下所示:

[x for y in collection for x in y] # [A for B in C for D in E]

在这里,发生了一些特别的事情。 我们希望我们的最终列表包含A项,而A项位于B项中,因此我们必须告诉列表理解。

  • A是将在结果列表中的项目
  • B是集合C中的每一项
  • C是集合本身
  • D是集合E中的每个项目(在这种情况下,也是A
  • E是另一个集合(在这种情况下, B

这个逻辑类似于普通的 for 循环:

for y in collection:     #      for B in C:
    for x in y:          #          for D in E: (in this case: for A in B)
        # receive x      #              # receive A

为了扩展这一点,并给出一个很好的例子+解释,想象一下有一列火车。

火车引擎(前面)总是会在那里(列表理解的结果)

那么,有任意数量的火车车厢,每个火车车厢的形式为: for x in y

列表理解可能如下所示:

[z for b in a for c in b for d in c ... for z in y]

这就像有这个常规的 for 循环:

for b in a:
    for c in b:
        for d in c:
            ...
                for z in y:
                    # have z

换句话说,在列表理解中,您只需将下一个循环添加到末尾,而不是向下一行并缩进。

回到火车的比喻:

Engine - Car - Car - Car ... Tail

什么是尾巴? 尾部在列表推导式中是一个特殊的东西。 不需要一个,但如果你有尾巴,尾巴是一个条件,看这个例子:

[line for line in file if not line.startswith('#')] 

这将为您提供文件中的每一行,只要该行不以主题标签 ( # ) 开头,其他行就会被跳过。

使用火车“尾部”的诀窍是在您从所有循环中获得最终“引擎”或“结果”的同时检查它的真/假,上面的例子是一个常规的 for 循环看起来像这样:

for line in file:
    if not line.startswith('#'):
        # have line

请注意:虽然在我对火车的比喻中,火车的末端只有一个“尾巴”,但条件或“尾巴”可以在每个“汽车”或循环之后......

例如:

>>> z = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> [x for y in z if sum(y)>10 for x in y if x < 10]
[5, 6, 7, 8, 9]

在常规 for 循环中:

>>> for y in z:
    if sum(y)>10:
        for x in y:
            if x < 10:
                print x

5
6
7
8
9

列表理解文档

提供列表推导式时,它由一个表达式组成,后跟至少一个for子句和零个或多个forif子句。 在这种情况下,新列表的元素是通过将每个 for 或 if 子句视为一个块,从左到右嵌套,并在每次到达最里面的块时计算表达式以生成一个列表元素而产生的元素.

换句话说,假设for循环是嵌套的。 从左到右阅读您的列表理解可以嵌套为:

for elem in vec:
    for num in elem:
        num           # the *single expression* from the spec

其中列表理解将使用最后一个最里面的块作为结果列表的值。

您的代码等于:

temp = []
for elem in vec:
    for num in elem:
        temp.append(num)

您可以将列表理解视为顺序语句。 这适用于任何级别的forif语句。

例如,考虑带有自己的if s 的 double for循环:

vec = [[1,2,3], [4,5,6], [7,8,9]]
result = [i for e in vec if len(e)==3 for i in e if i%2==0]

这里的列表理解与:

result = []
for e in vec: 
    if len(e)==3:
        for i in e:
            if i%2==0:
                result.append(i)

如您所见,列表推导式只是forif没有缩进但顺序相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM