解释嵌套列表理解如何工作?
- 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]
。问题是我无法理解中的语法[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_item
,lst
添加lst_item
到new_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 item
from each sublist
from相加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
是循环