简体   繁体   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]

This is tricking me out.这是在欺骗我。
I understand elem is the lists inside of the list from for elem in vic我知道 elem 是来自for elem in vic的列表中的列表
I don't quite understand the usage of num and for num in elem in the beginning and the end.我不太明白numfor num in elem的开头和结尾的用法。

How does python interpret this? python如何解释这个?
What's the order it looks at?它查看的顺序是什么?

Lets break it down.让我们分解它。

A simple list-comprehension:一个简单的列表理解:

[x for x in collection]

This is easy to understand if we break it into parts: [A for B in C]如果我们把它分成几部分,这很容易理解: [A for B in C]

  • A is the item that will be in the resulting list A是将在结果列表中的项目
  • B is each item in the collection C B是集合C中的每一项
  • C is the collection itself. C是集合本身。

In this way, one could write:这样,可以写:

[x.lower() for x in words]

In order to convert all words in a list to lowercase.为了将列表中的所有单词转换为小写。


It is when we complicate this with another list like so:当我们用另一个列表将其复杂化时,如下所示:

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

Here, something special happens.在这里,发生了一些特别的事情。 We want our final list to include A items, and A items are found inside B items, so we have to tell the list-comprehension that.我们希望我们的最终列表包含A项,而A项位于B项中,因此我们必须告诉列表理解。

  • A is the item that will be in the resulting list A是将在结果列表中的项目
  • B is each item in the collection C B是集合C中的每一项
  • C is the collection itself C是集合本身
  • D is each item in the collection E (in this case, also A ) D是集合E中的每个项目(在这种情况下,也是A
  • E is another collection (in this case, B ) E是另一个集合(在这种情况下, B

This logic is similar to the normal for loop:这个逻辑类似于普通的 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

To expand on this, and give a great example + explanation, imagine that there is a train.为了扩展这一点,并给出一个很好的例子+解释,想象一下有一列火车。

The train engine (the front) is always going to be there (the result of the list-comprehension)火车引擎(前面)总是会在那里(列表理解的结果)

Then, there are any number of train cars, each train car is in the form: for x in y那么,有任意数量的火车车厢,每个火车车厢的形式为: for x in y

A list comprehension could look like this:列表理解可能如下所示:

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

Which would be like having this regular for-loop:这就像有这个常规的 for 循环:

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

In other words, instead of going down a line and indenting, in a list-comprehension you just add the next loop on to the end.换句话说,在列表理解中,您只需将下一个循环添加到末尾,而不是向下一行并缩进。

To go back to the train analogy:回到火车的比喻:

Engine - Car - Car - Car ... Tail Engine - Car - Car - Car ... Tail

What is the tail?什么是尾巴? The tail is a special thing in list-comprehensions.尾部在列表推导式中是一个特殊的东西。 You don't need one, but if you have a tail, the tail is a condition, look at this example:不需要一个,但如果你有尾巴,尾巴是一个条件,看这个例子:

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

This would give you every line in a file as long as the line didn't start with a hashtag ( # ), others are just skipped.这将为您提供文件中的每一行,只要该行不以主题标签 ( # ) 开头,其他行就会被跳过。

The trick to using the "tail" of the train is that it is checked for True/False at the same time as you have your final 'Engine' or 'result' from all the loops, the above example in a regular for-loop would look like this:使用火车“尾部”的诀窍是在您从所有循环中获得最终“引擎”或“结果”的同时检查它的真/假,上面的例子是一个常规的 for 循环看起来像这样:

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

please note: Though in my analogy of a train there is only a 'tail' at the end of the train, the condition or 'tail' can be after every 'car' or loop...请注意:虽然在我对火车的比喻中,火车的末端只有一个“尾巴”,但条件或“尾巴”可以在每个“汽车”或循环之后......

for example:例如:

>>> 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]

In regular for-loop:在常规 for 循环中:

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

5
6
7
8
9

From the list comprehension documentation :列表理解文档

When a list comprehension is supplied, it consists of a single expression followed by at least one for clause and zero or more for or if clauses.提供列表推导式时,它由一个表达式组成,后跟至少一个for子句和零个或多个forif子句。 In this case, the elements of the new list are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached.在这种情况下,新列表的元素是通过将每个 for 或 if 子句视为一个块,从左到右嵌套,并在每次到达最里面的块时计算表达式以生成一个列表元素而产生的元素.

In other words, pretend that the for loops are nested.换句话说,假设for循环是嵌套的。 Reading from left to right your list comprehension can be nested as:从左到右阅读您的列表理解可以嵌套为:

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

where the list comprehension will use that last, innermost block as the values of the resulting list.其中列表理解将使用最后一个最里面的块作为结果列表的值。

Your code equals:您的代码等于:

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

You can look at list comprehension just as sequential statements.您可以将列表理解视为顺序语句。 This applies for any levels of for and if statements.这适用于任何级别的forif语句。

For example, consider double for loop with their own if s:例如,考虑带有自己的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]

Here the list comprehension is same as:这里的列表理解与:

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

As you can see list comprehension is simply for and if without indentations but in same sequence.如您所见,列表推导式只是forif没有缩进但顺序相同。

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

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