
在python中创建二维训练数据时,若反复复用同一列表对象并追加到外层列表,会导致所有子列表指向同一内存地址,从而引发数据被意外覆盖的问题。
在python中创建二维训练数据时,若反复复用同一列表对象并追加到外层列表,会导致所有子列表指向同一内存地址,从而引发数据被意外覆盖的问题。
这是一个典型的可变对象引用陷阱:当 tlistc 在循环外部定义(例如 tlistc = [0] * 14),并在每次迭代中仅修改其元素(如 tlistc[k] = s[k])时,你实际上始终在操作同一个列表对象。而执行 tlistm[e] = tlistc 并未复制该列表,只是将同一对象的引用存入 tlistm 的每个位置。因此,后续对 tlistc 的任何修改都会反映在 tlistm 中所有已存项上——这正是图中所有行内容最终一致的根本原因。
✅ 正确做法是:每次迭代都创建全新的独立列表。推荐使用以下任一方式:
for e in range(episodes):
qm = random.randint(0, 5)
env.game(action)
fps.tick(1)
screen.fill(bgcolor)
s = env.get_state()
rew = s[12]
q1 = rew + g * qm
# ✅ 方案1:直接构造新列表(推荐,简洁且明确)
tlistc = s[:12] + [action, q1] # 前12个状态 + action + q1,共14项
# ✅ 方案2:使用copy()(若需保留原逻辑结构)
# tlistc = s[:12][:] # 浅拷贝前12项
# tlistc.extend([action, q1])
tlistm.append(tlistc) # 直接append,无需预分配索引
if s[13] == 1:
env.game_reset()
action = random.randint(0, 3)⚠️ 注意事项:
- 避免 tlistm[e] = tlistc 这类基于预分配索引的赋值(尤其当 tlistm 初始为空或长度不足时易引发 IndexError);
- 优先使用 tlistm.append(...) 动态扩展列表;
- 若 s 是 NumPy 数组,注意 .tolist() 或切片会生成新 Python 列表;纯 Python 列表切片 s[:12] 也返回新副本;
- 不要使用 tlistc = tlistc.copy() 或 tlistc[:] 在循环内“重用”旧变量——应彻底重建。
总结:Python 中列表是可变对象,赋值即传递引用。构建二维数据时,务必确保每行数据为独立对象。通过在循环内构造新列表(而非复用+修改),即可彻底规避数据污染问题,确保训练样本准确、互不干扰。
立即学习“Python免费学习笔记(深入)”;


















