嵌套列表理解如何工作的解释?

Alv*_*tes 55 python list

我理解这一点没有问题:

a = [1,2,3,4]
b = [x for x in a]
Run Code Online (Sandbox Code Playgroud)

我以为就是这样,但后来我找到了这个片段:

a = [[1,2],[3,4],[5,6]]
b = [x for xs in a for x in xs]
Run Code Online (Sandbox Code Playgroud)

这使得b = [1,2,3,4,5,6].问题是我在理解语法方面遇到了麻烦[x for xs in a for x in xs],有人能解释一下它是如何工作的吗?

wim*_*wim 65

啊,难以理解的"嵌套"理解.循环以与理解中相同的顺序展开.

[leaf for branch in tree for leaf in branch]
Run Code Online (Sandbox Code Playgroud)

它有助于像这样思考它.

for branch in tree:
    for leaf in branch:
        yield leaf
Run Code Online (Sandbox Code Playgroud)

PEP202断言这句法与"最后的指数变化最快的"是"正确的",特别是没有的解释为什么.

  • 对于它的价值,难道你不认为`[树枝上树叶的叶子]更易于人类阅读?希望这是另一种方式. (17认同)
  • 我不认为它们中的任何一个都非常易读:^) (8认同)
  • 感谢@Greenstick,n 维实际上使这更容易理解。`[原子 代表宇宙中的星系 代表星系中的恒星系统 代表恒星系统中的行星 代表大陆 代表大陆中的生态系统 代表森林中的生态系统 代表树中的森林 代表树枝中的树 代表叶子中的树枝 代表静脉中的叶 代表纤维中的静脉 代表细胞中的细胞纤维用于细胞中的分子用于分子中的原子]` (5认同)
  • 也许它需要知道`leaf`之前存在`branch`?从左到右阅读理解. (2认同)
  • @Ray绝对可以,但这似乎是一种随意的必需品.仅仅因为Python需要从左到右阅读它并不意味着无法将其从右向左读取以提高可读性. (2认同)
  • 通常的习惯用语“for a in A”定义了“a”并期望“A”已经被定义。python 中推导式的选择顺序保留了这一点。值不值2分钱我也不知道.. (2认同)
  • 我很难进一步概括这一点。具体来说,如何将其扩展到 n 维列表?离开这里的例子,我终于弄清楚了 n = 3 的情况:“[森林​​中的叶子换树中的树枝换树枝中的叶子]”回想起来非常简单。 (2认同)

Ada*_*ith 25

if a = [[1,2],[3,4],[5,6]],那么如果我们展开那个列表comp,我们得到:

      +----------------a------------------+ 
      | +--xs---+ , +--xs---+ , +--xs---+ | for xs in a
      | | x , x |   | x , x |   | x , x | | for x in xs
a  =  [ [ 1 , 2 ] , [ 3 , 4 ] , [ 5 , 6 ] ]
b  =  [ x for xs in a for x in xs ] == [1,2,3,4,5,6] #a list of just the "x"s
Run Code Online (Sandbox Code Playgroud)


fal*_*tru 10

b = [x for xs in a for x in xs] 类似于以下嵌套循环.

b = []
for xs in a:
   for x in xs:
       b.append(x)
Run Code Online (Sandbox Code Playgroud)


the*_*eye 6

可以这样写

result = []
for xs in a:
    for x in xs:
        result.append(x)
Run Code Online (Sandbox Code Playgroud)

你可以在这里阅读更多关于它的信息


Ffi*_*ydd 6

有效地:

...for xs in a...]
Run Code Online (Sandbox Code Playgroud)

正在迭代您的主(外部)列表并依次返回您的每个子列表。

...for x in xs]
Run Code Online (Sandbox Code Playgroud)

然后迭代这些子列表中的每一个。

这可以重写为:

b = []
for xs in a:
    for x in xs:
        b.append(x)
Run Code Online (Sandbox Code Playgroud)


See*_*pha 5

这是嵌套理解的一个例子。将其a = [[1,2],[3,4],[5,6]]视为 3 x 2 矩阵(矩阵 = [[1,2],[3,4],[5,6]])。

       ______
row 1 |1 | 2 |
       ______
row 2 |3 | 4 |
       ______
row 3 |5 | 6 |
       ______
Run Code Online (Sandbox Code Playgroud)

您看到的列表推导式是将矩阵中的所有元素放入列表的另一种方法。

我将尝试使用不同的变量来解释这一点,这有望更有意义。

b = [element for row in matrix for element in row]
Run Code Online (Sandbox Code Playgroud)

第一个 for 循环遍历矩阵 ie 内的行[1,2],[3,4],[5,6]。第二个 for 循环遍历 2 个元素列表中的每个元素。

我在我的网站http://programmathics.com/programming/python/python-list-comprehension-tutorial/上写了一篇关于 List Comprehension 的小文章,它实际上涵盖了与这个问题非常相似的场景。我还给出了一些关于python列表理解的其他例子和解释。

免责声明:我是该网站的创建者。


Joh*_*oda 5

这是我最好记住的方式:(伪代码,但具有这种类型的模式)

[(x,y,z) (loop 1) (loop 2) (loop 3)]
Run Code Online (Sandbox Code Playgroud)

其中最右边的循环(循环 3)是最内层的循环。

[(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)]
Run Code Online (Sandbox Code Playgroud)

其结构如下:

for x in range(3):
    for y in range(3):
        for z in range(3):
            print((x,y,z))
Run Code Online (Sandbox Code Playgroud)

编辑我想添加另一种模式:

[(result) (loop 1) (loop 2) (loop 3) (condition)]
Run Code Online (Sandbox Code Playgroud)

前任:

[(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)    if x == y == z]
Run Code Online (Sandbox Code Playgroud)

有这种类型的结构:

for x in range(3):
    for y in range(3):
        for z in range(3):
            if x == y == z:
                print((x,y,z))



Run Code Online (Sandbox Code Playgroud)