Python 2.7 三维dict列表赋值后遍历显示全为迭代器最大值问题
异常原因
问题核心是Python对可变对象的引用传递规则,和Python 2.7版本本身无关,具体执行逻辑如下:
- 函数开头先定义了单个字典对象
frameData = {'textFrameName': ''} - 构建三维
framesData列表时,三层列表推导的所有内存位置,存储的都是这同一个字典的引用,没有为每个(p,x,y)坐标点创建独立的字典实例 - 后续循环给每个坐标点的
textFrameName赋值时,本质上都是在修改这唯一一个共享字典的属性:createFrames里的print语句在每次赋值完成后立刻执行,因此当时看到的是刚被修改的当前循环坐标值,造成了“数据按顺序正确写入”的假象- 等所有循环执行完毕,这个共享字典的
textFrameName最终被赋值为最后一次未被跳过的坐标值,也就是x循环到最大值12、y循环到最大值20对应的字符串
- 后续
displayData遍历三维列表时,无论取哪个坐标位置,拿到的都是同一个共享字典对象,因此所有输出内容都统一为这个最终的最大值字符串
最简复现逻辑示例:
shared_dict = {'val': 0} # 二维列表所有位置都指向同一个shared_dict grid = [[shared_dict for _ in range(2)] for _ in range(2)] # 修改任意位置的属性,所有位置的内容都会同步变化 grid[0][0]['val'] = 5 print(grid[1][1]['val']) # 输出5 grid[1][1]['val'] = 10 print(grid[0][0]['val']) # 输出10
修复方案
修改三维列表的初始化逻辑,不要在列表推导中引用外部定义的共享字典,为每个坐标位置单独实例化独立的空字典,从根源上断开引用关联。
把原代码中的初始化行:
framesData = [[[frameData for y in range(yCount)] for x in range(xCount)] for p in range(numPages)]
替换为:
# 每个位置单独创建独立的字典实例,不存在共享引用 framesData = [[[{'textFrameName': ''} for y in range(yCount)] for x in range(xCount)] for p in range(numPages)]
如果需要复用固定的字典结构,也可以通过深拷贝实现独立实例,避免直接引用共享对象:
from copy import deepcopy base_frame = {'textFrameName': ''} framesData = [[[deepcopy(base_frame) for y in range(yCount)] for x in range(xCount)] for p in range(numPages)]
修改完成后,每个(p,x,y)坐标位置的字典都是独立的内存对象,后续给不同位置的textFrameName赋值时,只会修改对应位置的字典内容,不会影响其他位置,displayData输出的内容就会和createFrames循环时打印的顺序值保持一致。
内容的提问来源于stack exchange,提问作者RBE。
相关产品推荐
相关产品推荐

