理解嵌套列表推导式
理解嵌套列表推导式
我想要理解嵌套列表推导式。
下面,我列出了一个列表推导式及其等价的for循环表达式。
我想知道我对它们的理解是否正确。
例如,
[(min([row[i] for row in rows]),max([row[i] for row in rows])) for i in range(len(rows[0]))]
等价于
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)
如果我可以概括一下,我猜测
[exp2([exp1 for x in xSet]) for y in ySet]
的形式可以翻译成以下内容。(我希望我在这方面是正确的)
result=[] for y in ySet: innerResult =[] for x in xSet: innerResult.append(exp1) exp2Result = exp2(innerResult) result.append(exp2Result)
对于更简单的情况,
[exp1 for x in xSet for y in ySet]
等于
result=[] for x in xSet: for y in ySet: result.append(exp1)
而,
[[exp1 for x in xSet] for y in ySet]
等于
result=[] for y in ySet: innerResult=[] for x in xSet: innerResult.append(exp1) result.append(innerResult)
我在Equivalent for loop expression for complex list comprehension上问过类似的问题。
那里给出的答案在了解了内部工作原理后重构了形式。
我想了解它是如何系统地工作的,这样我就可以将这个概念应用到其他稍有不同的例子中。
理解嵌套列表推导的原因是为了在多维数组上进行操作,通常在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]]
如你所见,“嵌套”是通过对矩阵的每个维度进行操作来实现的。在你提供的例子中,`ySet`(不幸的是,这个名字不太好,因为`sets`是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)]
你可以尝试使用内置的`zip`函数:
zip(rows[0], rows[1]) [(1, 10), (2, 20), (3, 30)]
或者更简洁优雅的写法:
zip(*rows) [(1, 10), (2, 20), (3, 30)]
希望对你有所帮助!
理解嵌套列表推导的原因和解决方法
嵌套列表推导是Python中一种强大且灵活的语法特性,可以在一个列表推导中嵌套另一个列表推导。然而,对于初学者来说,可能会遇到一些困惑和错误。
在Python语言参考手册的表达式部分有详细介绍了这个问题。特别要注意的是,多个for循环在一个列表推导中的嵌套顺序始终是从左到右。例如,在以下示例中:
matrix = [[1, 2], [3, 4]] [item for item in row for row in matrix] # 错误!
上述代码会出现错误,因为变量row在定义之前就被使用了。正确的嵌套顺序应该是从左到右,如下所示:
[item for row in matrix for item in row] # 嵌套顺序是从左到右
然而,在Python语言参考手册中并没有对[[exp for item in row] for row in matrix]这种格式的列表推导进行特殊的语法解释。这是因为这个例子并没有使用任何特殊的语法,只是两个简单的列表推导而已。第一个[exp for item in row]将根据给定的row创建一个列表。外部的列表推导将创建一个列表,其中每个项都是由“内部”列表推导创建的列表,每一行都有一个。
关于[[list comprehension] list comprehension]格式的顺序,Python文档中没有专门的章节。原因是在列表推导中,对每个项进行求值的表达式可以是任何有效的Python表达式。在这个上下文中,一个“内部”列表推导就像任何其他的Python表达式一样。
虽然这种顺序可能让人感到惊讶,但它与在代码中嵌套的for循环的顺序相同。根据我记得的,这种顺序是这样的原因。
Guido的思维方式通常与我的不同,但这里也不例外。无论如何,通过理解嵌套列表推导的原因和解决方法,我们可以更好地利用这个强大的Python语法特性。