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

2024-12-06 08:40:00
admin
原创
150
摘要:问题描述:我能毫无困难地理解这一点:a = [1,2,3,4] b = [x for x in a] 我以为这就是全部了,但后来我发现了这个片段:a = [[1,2],[3,4],[5,6]] b = [x for xs in a for x in xs] 这使得b = [1,2,3,4,5,6]。问题是我无...

问题描述:

我能毫无困难地理解这一点:

a = [1,2,3,4]
b = [x for x in a]

我以为这就是全部了,但后来我发现了这个片段:

a = [[1,2],[3,4],[5,6]]
b = [x for xs in a for x in xs]

这使得b = [1,2,3,4,5,6]。问题是我无法理解中的语法[x for xs in a for x in xs],有人可以解释一下它是如何工作的吗?


解决方案 1:

啊,难以理解的“嵌套”推导。循环按照与推导相同的顺序展开。

[leaf for branch in tree for leaf in branch]

这样想是有帮助的。

for branch in tree:
    for leaf in branch:
        yield leaf

PEP202断言这种“最后一个索引变化最快”的语法是“正确的”,但特别没有解释为什么

解决方案 2:

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

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

解决方案 3:

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

b = []
for xs in a:
   for x in xs:
       b.append(x)

解决方案 4:

有效地:

...for xs in a...]

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

...for x in xs]

然后对每个子列表进行迭代。

这可以重写为:

b = []
for xs in a:
    for x in xs:
        b.append(x)

解决方案 5:

可以这样写

result = []
for xs in a:
    for x in xs:
        result.append(x)

您可以在此处阅读更多相关信息

解决方案 6:

这是嵌套推导式的示例。将其视为a = [[1,2],[3,4],[5,6]]一个 3×2 矩阵(矩阵 = [[1,2],[3,4],[5,6]])。

       ______
row 1 |1 | 2 |
       ______
row 2 |3 | 4 |
       ______
row 3 |5 | 6 |
       ______

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

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

b = [element for row in matrix for element in row]

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

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

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

解决方案 7:

我记得最清楚的是这样的:(伪代码,但有这种模式)

[(x,y,z) (loop 1) (loop 2) (loop 3)]

其中最右边的循环(循环 3)是最里面的循环。

[(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)]

结构如下:

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

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

[(result) (loop 1) (loop 2) (loop 3) (condition)]

前任:

[(x,y,z)    for x in range(3)    for y in range(3)    for z in range(3)    if x == y == z]

具有以下类型的结构:

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



解决方案 8:

是的,你可以在列表推导中嵌套 for 循环。你甚至可以在其中嵌套 if 语句。

dice_rolls = []
for roll1 in range(1,7):
    for roll2 in range(1,7):
        for roll3 in range(1,7):
            dice_rolls.append((roll1, roll2, roll3))

# becomes

dice_rolls = [(roll1, roll2, roll3) for roll1 in range(1, 7) for roll2 in range(1, 7) 
              for roll3 in range(1, 7)]

我在 Medium 上写了一篇短文,解释了列表推导和一些其他可以用 Python 做的很酷的事情,如果你感兴趣的话可以看一下:)

解决方案 9:

您要求的是嵌套列表。

让我尝试逐步回答这个问题,涵盖以下主题:

  • For 循环

  • 列表推导

  • 嵌套 for 循环和列表推导


For 循环

您有此列表:lst = [0,1,2,3,4,5,6,7,8]并且想要一次迭代列表中的一项并将其添加到新列表中。您可以执行一个简单的 for 循环:

lst = [0,1,2,3,4,5,6,7,8]
new_list = []

for lst_item in lst:
    new_list.append(lst_item)

您可以使用列表推导做完全相同的事情(它更具 Python 风格)。

列表理解

列表推导是一种(*有时)更简单、更优雅的创建列表的方法。

new_list = [lst_item for lst_item in lst]

你可以这样读:对于每一个lst_itemlst添加lst_itemnew_list

嵌套列表

什么是嵌套列表? 一个简单的定义:它是一个包含子列表的列表。 列表中有一个列表。

根据您与谁交谈,嵌套列表*是列表推导比常规 for 循环更难阅读的情况之一。

假设您有这个嵌套列表:nested_list = [[0,1,2], [3,4,5], [6,7,8]],并且您想将其转换为像这样的扁平列表:flattened list = [0,1,2,3,4,5,6,7,8]

如果您使用与以前相同的 for 循环,那么您将无法获得它。

flattened_list = []
for list_item in nested_list:
    flattened_list.append(list_item)

为什么?因为每个list_item实际上是子列表之一。在第一次迭代中,您将获得[0,1,2],然后是[3,4,5],最后是[6,7,8]

您可以这样检查:

nested_list[0] == [0, 1, 2]
nested_list[1] == [3, 4, 5]
nested_list[2] == [6, 7, 8]

您需要一种方法来进入子列表并将每个子列表项添加到flattened list

How?您添加了额外的迭代层。实际上,您为每一层子列表添加一个迭代层。

在上面的例子中,有两个层。

for 循环解决方案。

nested_list = [[0,1,2], [3,4,5], [6,7,8]]

flattened_list = []
for sublist in nested_list:
    for item in sublist:
        flattened_list.append(item)

让我们大声读出这段代码。

for sublist in nested_list:每个子列表是[0,1,2][3,4,5][6,7,8]。在第一个循环的第一次迭代中,我们进入[0,1,2]

for item in sublist:的第一项[0,1,2]0,它被附加到flattened_list。然后是1,最后是2

直到这一点flattened_list为止[0,1,2]

我们完成了第二个循环的最后一次迭代,因此我们进入第一个循环的下一次迭代。我们进入内部[3,4,5]

然后我们转到此子列表的每个项目并将其附加到flattened_list。然后我们进行下一次迭代,依此类推。

你如何使用列表推导来实现这一点?

列表理解解决方案。

flattened_list = [item for sublist in nested_list for item in sublist]

您可以这样读:将 each itemfrom each sublistfrom相加nested_list

它更简洁,但如果有很多层,它可能会变得更加困难。

让我们一起看看

#for loop
nested_list = [[0,1,2], [3,4,5], [6,7,8]]

flattened_list = []
for sublist in nested_list:
    for item in sublist:
        flattened_list.append(item)

----------------------------------------------------------------------

#list comprehension
flattened_list = [item for sublist in nested_list for item in sublist]

迭代层数越多,添加的就越多for x in y


编辑于 2021 年 4 月。

您可以使用Numpy展平嵌套列表。从技术上讲,在 Numpy 中,该术语应为“数组”。

对于小列表来说,这有点小题大做,但如果您要处理列表中数百万个数字,则可能需要 Numpy。

来自 Numpy 的文档。我们有一个属性 flat

b = np.array(
[
  [ 0,  1,  2,  3],
  [10, 11, 12, 13],
  [20, 21, 22, 23],
  [30, 31, 32, 33],
  [40, 41, 42, 43]
]
)

for element in b.flat:
    print(element)

0
1
2
...
41
42
43

解决方案 10:

该语法中的整个混乱是由于第一个变量和错误的命名约定而引起的。

[door for room in house for door in room]

这里的“门”才是让人困惑的地方

想象一下,如果一开始没有“门”变量

[for room in house for door in room]

这样我们就能做得更好。

使用 [x, xs, y] 等变量会变得更加混乱,因此变量命名也是一个关键

您还可以对循环变量执行一些操作,例如:

doors = [door for room in house for door in str(room)]

这相当于:

for room in house:
    for door in str(room):
        bolts.append(door)

解决方案 11:

英语语法:

b = "a list of 'specific items' taken from 'what loop?' "
b = [x for xs in a for x in xs]

x 是特定项目

for xs in a for x in xs是循环

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用