You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用生成器构造pandas DataFrame出现数据全重复问题排查

异常原因

这个问题和pandas、生成器的原生迭代逻辑无关,根因是transform_xml生成器的实现存在对象引用错误:

  • 你在写transform_xml时,大概率在遍历XML节点的循环外部,提前初始化了一个存储商品字段的字典
  • 遍历每个XML节点时,你只是修改这同一个字典的键值,之后直接yield这个字典对象,没有在每次循环时新建独立的字典实例
  • 前三次调用next(trans)时,你拿到字典引用后立刻执行打印,此时字典还没被下一次迭代修改,所以输出的3条商品数据看起来是正常的。但这三次返回值本质上都是同一个字典对象的引用,如果你把这三个返回值存为变量,等生成器迭代完成后再查看,值也会被覆盖。
  • 当你用list(trans)批量收集生成器剩余内容时,列表里存储的全是指向这同一个字典的引用。等生成器迭代到最后一条Kenzo商品数据时,字典的内容就被固定为这条Kenzo商品的字段,最终列表里的所有元素、转成DataFrame后的所有行,就全是最后一条Kenzo数据的重复值。
错误写法复现

会触发该问题的生成器典型写法如下:

def transform_xml(eroot):
    item = {}  # 循环外仅初始化1次字典
    for node in eroot.iter("product"):
        # 每次迭代仅修改同一个字典的键值
        item["MANUFACTURER"] = node.findtext("manufacturer")
        item["NAME"] = node.findtext("name")
        item["EAN"] = node.findtext("ean")
        item["id"] = node.findtext("id")
        item["SIZE"] = node.findtext("size")
        yield item  # 每次返回的都是同一个字典的引用
修复方案

把字典的初始化逻辑移到循环内部,保证每次迭代都生成一个全新的独立字典实例再返回即可:

def transform_xml(eroot):
    for node in eroot.iter("product"):
        # 每次循环新建独立字典,不存在引用覆盖问题
        item = {
            "MANUFACTURER": node.findtext("manufacturer"),
            "NAME": node.findtext("name"),
            "EAN": node.findtext("ean"),
            "id": node.findtext("id"),
            "SIZE": node.findtext("size")
        }
        yield item

你可以用一个小测试验证修复效果:修复后把前三次next(trans)的返回值分别存为变量,执行a is b判断会返回False,说明三个返回值是独立的字典对象,不会再出现值被覆盖、DataFrame行重复的问题。


内容的提问来源于stack exchange,提问作者Айдын

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:09:22