You need to enable JavaScript to run this app. Python 2.7 三维dict列表赋值后遍历显示全为迭代器最大值问题
优惠活动
大模型
产品
解决方案
定价
更多

Python 2.7 三维dict列表赋值后遍历显示全为迭代器最大值问题

异常原因

问题核心是Python对可变对象的引用传递规则,和Python 2.7版本本身无关,具体执行逻辑如下:

  • 函数开头先定义了单个字典对象frameData = {'textFrameName': ''}
  • 构建三维framesData列表时,三层列表推导的所有内存位置,存储的都是这同一个字典的引用,没有为每个(p,x,y)坐标点创建独立的字典实例
  • 后续循环给每个坐标点的textFrameName赋值时,本质上都是在修改这唯一一个共享字典的属性:
    1. createFrames里的print语句在每次赋值完成后立刻执行,因此当时看到的是刚被修改的当前循环坐标值,造成了“数据按顺序正确写入”的假象
    2. 等所有循环执行完毕,这个共享字典的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。

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 13:06:01