了解嵌套列表理解

eug*_*ene 72 python nested list-comprehension

我想了解嵌套列表理解.下面,我列出了一个列表推导表达式和它们的for循环等价物.
我想知道我的理解是否正确.

例如,

[(min([row[i] for row in rows]),max([row[i] for row in rows])) 
for i in range(len(rows[0]))]
Run Code Online (Sandbox Code Playgroud)

相当于

result=[]
for i in range(len(rows[0])):
  innerResult=[]
  for row in rows:
    innerResult.append(row[i])
  innerResult2=[]
  for row in rows:
    innerResult2.append(row[i])
  tuple=(min(innerResult), max(innerResult2))
  result.append(tuple)
Run Code Online (Sandbox Code Playgroud)

如果我可以概括,我想

[exp2([exp1 for x in xSet]) for y in ySet]
Run Code Online (Sandbox Code Playgroud)

表格可以翻译成以下内容.(我希望我对此是正确的)

result=[]
for y in ySet:
  innerResult =[]
  for x in xSet:
    innerResult.append(exp1)
  exp2Result = exp2(innerResult)
  result.append(exp2Result)
Run Code Online (Sandbox Code Playgroud)

对于更简单的情况,

[exp1 for x in xSet for y in ySet] 
Run Code Online (Sandbox Code Playgroud)

等于

result=[] 
for x in xSet:
  for y in ySet: 
    result.append(exp1)
Run Code Online (Sandbox Code Playgroud)

然而,

[[exp1 for x in xSet] for y in ySet]
Run Code Online (Sandbox Code Playgroud)

等于

result=[]
for y in ySet:
  innerResult=[]
  for x in xSet:
    innerResult.append(exp1)
  result.append(innerResult)
Run Code Online (Sandbox Code Playgroud)

我问了一个关于等价的类似问题,用于复杂列表理解
循环表达式给出的答案在理解了它在内部的作用之后重构了形式.
我想知道它是如何系统地工作的,所以我可以将这个概念应用于其他略有不同的例子.

tal*_*nat 72

的确,你是对的.这在Python语言参考表达式部分中有详细描述.

特别注意for在单个列表理解中嵌套几个s 的顺序,它总是从左到右:

>>> matrix = [[1, 2], [3, 4]]
>>> [item for item in row for row in matrix] # oops!
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    [item for item in row for row in matrix]
NameError: name 'row' is not defined
>>> [item for row in matrix for item in row] # nesting is in left-to-right order
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

  • 在我所知道的文档中没有这样的部分.原因是在列表推导中,为每个项目计算的表达式可以是任何有效的Python表达式.在这种情况下,"内部"列表理解就像任何其他Python表达式一样. (3认同)
  • 哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇 (2认同)

mac*_*mac 71

简短的回答是:是的,你的理解是正确的.

只有一个问题:你通常在python代码中使用嵌套列表理解的方式是在多维数组上操作.

一个典型的例子是当您对矩阵进行操作时:

>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [[el - 1 for el in row] for row in matrix]
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,"嵌套"通过对矩阵的每个维度进行操作而起作用.

在你提供的例子中,似乎ySet[不幸的名称btw,因为集合是python提供的类型之一]只是一个通用的计数器,这使得更难以跟踪幕后发生的事情.

至于你的第一个例子:

>>> rows = ([1, 2, 3], [10, 20, 30])
>>> [(min([row[i] for row in rows]),max([row[i] for row in rows])) for i in range(len(rows[0]))]
[(1, 10), (2, 20), (3, 30)]
Run Code Online (Sandbox Code Playgroud)

您可能希望查看zip内置函数:

>>> zip(rows[0], rows[1])
[(1, 10), (2, 20), (3, 30)]
Run Code Online (Sandbox Code Playgroud)

或者为了最大限度地简洁和优雅:

>>> zip(*rows)
[(1, 10), (2, 20), (3, 30)]
Run Code Online (Sandbox Code Playgroud)

HTH!