列表推导式循环顺序差异疑问:为何输出不符合预期?
为什么这两个列表推导式的输出差异这么大?
先看你的测试代码:
import numpy as np xtest=np.arange(0,10) ytest=np.arange(0,3) zValuesBisBis=[[j for j in xtest] for i in ytest] zValuesBisBisBis=[j for j in xtest for i in ytest] print(zValuesBisBis) print(zValuesBisBisBis)
输出结果:
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]
核心原因:列表推导式的循环执行顺序
你觉得循环顺序“看似一致”,但实际上这两个推导式的循环逻辑完全不同:
嵌套列表推导式(zValuesBisBis)
这个推导式的结构是[内层列表推导 for 外层循环],执行顺序是:- 先跑外层循环
for i in ytest(总共3次循环,对应ytest的3个元素) - 每一次外层循环时,执行内层的
[j for j in xtest],生成一个完整的xtest列表 - 最终把这3个列表收集起来,就得到了包含3个子列表的嵌套结构。
- 先跑外层循环
单层列表推导式(zValuesBisBisBis)
这个推导式没有嵌套,是[表达式 for 循环1 for 循环2]的结构,执行顺序是从左到右依次遍历循环:- 先跑第一个循环
for j in xtest(遍历0到9) - 对于每一个j,再跑第二个循环
for i in ytest(遍历0到2,共3次) - 每一次内层循环(i的循环),都会把当前的j添加到结果列表中
- 所以每个j会被重复添加3次,最终就形成了“每个xtest元素重复ytest长度次”的结果。
- 先跑第一个循环
如何得到嵌套列表的扁平化结果?
如果想把zValuesBisBis扁平化,你需要调整循环顺序,让外层循环是i in ytest,内层是j in xtest,也就是:
z_flattened = [j for i in ytest for j in xtest]
这样执行顺序是:先遍历i(3次),每次遍历i时再遍历j(10次),把每个j依次添加,最终得到的就是[0,1,...,9,0,1,...,9,0,1,...,9],也就是嵌套列表的扁平化结果。
内容的提问来源于stack exchange,提问作者StarBucK
相关产品推荐
相关产品推荐

