Python迭代对象中整数按引用保存导致ID重复问题排查
问题分析与解决方案
核心问题:字典引用传递导致的覆盖
你的代码里所有页面ID最终都是cnt的最终值,根源不是字符串关联了cnt的引用(字符串是不可变类型,一旦创建就不会被后续修改),而是字典的引用赋值错误:
tmpPage = page
这行代码并没有创建新字典,只是让tmpPage指向原page字典的内存地址。循环中每次修改tmpPage的content或metadata['id'],都是直接修改原page对象。最后用dict(tmpPage)转成新字典时,原page的metadata['id']已经被最后一次循环修改,所以所有添加到pages里的字典,ID都会是最后一次的cnt值。
修复方案:深拷贝原字典
要解决这个问题,需要每次循环都创建原page的独立副本,而不是引用。Python的copy模块提供了deepcopy方法,可以递归复制所有嵌套对象(包括metadata这种子字典):
修改后的代码:
import copy def chunk_page(page): pages = [] chunks = chunk_string(page['content'], 500, 40) cnt = 0 for chunk in chunks: # 深拷贝原page,创建独立的新字典 tmpPage = copy.deepcopy(page) # 处理chunk(保留原逻辑) if cnt == 1: chunk = chunk[0:chunk.rfind(' ')] else: chunk = chunk[chunk.find(' '): chunk.rfind(' ')] tmpPage['content'] = chunk # 生成新ID if '_' in tmpPage['metadata']['id']: base_id = page['metadata']['id'].split('_')[0] tmpPage['metadata']['id'] = f"{base_id}_{cnt}" else: tmpPage['metadata']['id'] = f"{page['metadata']['id']}_{cnt}" pages.append(tmpPage) cnt += 1 return pages
额外优化说明
- 移除了无用的
ints列表(原代码仅存储cnt但未实际使用)。 - 用f-string替代繁琐的字符串拼接,更简洁易读。
- 处理带下划线的ID时,改用
split('_')[0]获取基础ID,比原代码的[0:-1]更可靠(避免原ID末尾非数字的情况)。
内容的提问来源于stack exchange,提问作者Nikita Kholodnyi
相关产品推荐
相关产品推荐

