【发布时间】:2016-04-06 02:01:55
【问题描述】:
我对这个列表理解有点困惑:
l = [[i * j for j in range(3, 5)] for i in range(3)]
按什么顺序执行?
【问题讨论】:
标签: python list list-comprehension
我对这个列表理解有点困惑:
l = [[i * j for j in range(3, 5)] for i in range(3)]
按什么顺序执行?
【问题讨论】:
标签: python list list-comprehension
这是一个非常普通的表单列表理解:
[expression for var in iterable]
在这种情况下,expression 恰好是另一个列表解析。因此,内部理解将对外部迭代产生的每个项目进行一次评估。
如果我们将内部理解分解为一个函数,可能会感觉更清楚一点:
def inner(i):
return [i * j for j in range(3, 5)]
l = [inner(i) for i in range(3)]
现在我们更清楚地看到(希望无论如何)外部理解导致内部理解为range(3) 中的每个“i”执行一次。
【讨论】:
想象一下它是从外向内执行的。
[X for i in range(3)]
在这种情况下,X 本身就是另一个列表推导:
[i*j for j in range(3,5)]
其中i 绑定到单个值。
所以它扩展为[[0*3,0*4],[1*3,1*4],[2*3,2*4]],或[[0,0],[3,4],[6,8]],
【讨论】:
如下:
l = [[i * j for j in range(3, 5)] for i in range(3)]
i 采用值 0、1 和 2。对于i 的每个值,都会评估嵌套列表推导并将结果保存到顶级列表:
[i * j for j in range(3, 5)]
这里,j 采用值 3 和 4。对于每个值,保存j 与当前值i 的乘积。
对于i 的第一个值,即0,这是0 乘以j 值,所以你得到[0, 0]。
对于i 的第二个值,即1,这是1 乘以j 值,所以你得到[3, 4]。
对于i 的第三个值,即2,这是2 乘以j 值,所以你得到[6, 8]。
最终的结果就是这三个子列表组成的列表,所以得到:
[[0, 0], [3, 4], [6, 8]]
【讨论】:
l = [[i * j for j in range(3, 5)] for i in range(3)]
可以想象为:
(1) l = [[i * j for j in range(3, 5)] with i = 0] => [[0*3, 0*4]]= [[0,0]]
+(2) l = [[i * j for j in range(3, 5)] with i = 1] =>[[0,0], [3,4]]
+(3) l = [[i * j for j in range(3, 5)] with i = 2] =>[[0,0], [3,4], [6,8]]
【讨论】: