使用生成器推导式创建Pandas数据帧时为何得到实际DataFrame而非生成器对象
核心原理解释
你对生成器的基础认知是正确的:带圆括号的推导式本身确实会生成惰性求值的生成器对象,不会在定义阶段就立刻生成全部的DataFrame内容。出现认知偏差的核心,是没有注意到解包赋值操作会自动触发生成器的完整迭代流程,具体逻辑可以拆成两步看:
- 首先,代码中
(pd.DataFrame(rng.rand(nrows, ncols)) for i in range(4)这部分在执行时,只会生成一个等待触发的生成器实例,不会立刻运行循环逻辑产出DataFrame。如果单独把这个生成器赋值给单个变量,比如写gen = (pd.DataFrame(rng.rand(nrows, ncols)) for i in range(4)),此时查看type(gen)会得到<class 'generator'>,完全符合你对生成器的认知。 - 其次,Python中的解包赋值(即左侧同时排列多个变量的赋值语法),本质是强制对右侧的可迭代对象做全量遍历,按照迭代返回值的顺序,依次给左侧的变量赋值。当生成器对象被放到解包赋值的右侧时,Python会自动逐次调用生成器的
__next__()方法,直到生成器迭代结束:- 第一次取迭代值时,生成器执行第一轮循环逻辑,生成第一个DataFrame,赋值给
df1 - 第二次取迭代值时,生成器执行第二轮循环,生成第二个DataFrame,赋值给
df2 - 重复这个过程直到生成器把4次循环的内容全部产出,最终四个变量拿到的都是实际生成的DataFrame对象,而非那个空的生成器本身。
- 第一次取迭代值时,生成器执行第一轮循环逻辑,生成第一个DataFrame,赋值给
补充验证:如果可迭代对象的长度和左侧变量数量不匹配,解包操作会直接抛出
ValueError: not enough values to unpack或ValueError: too many values to unpack的报错,这也能佐证解包操作确实是在遍历、拆分可迭代对象的内部元素,而非直接把整个右侧对象赋值给第一个变量。
内容的提问来源于stack exchange,提问作者jgg
相关产品推荐
相关产品推荐

