Python for循环中Augmented assignment引发theta_list存值全为最终值异常咨询
异常行为的核心成因
两种赋值操作对numpy数组的内存操作逻辑存在本质差异,直接导致列表存储结果出现偏差:
两类赋值的执行逻辑差异
- 普通赋值
theta = theta - eta * loss_grad(theta, x, y)
计算时会在内存中开辟一块全新的独立数组空间存放计算结果,随后将变量theta的引用绑定到这块新空间,全程不会修改初始theta对应的内存块内容。 - 增强赋值
theta -= eta * loss_grad(theta, x, y)
属于原地修改(in-place)操作:不会新建独立数组,而是直接在theta当前指向的已有内存块上完成数值减计算,整个过程中theta变量绑定的内存地址始终没有变化。
列表异常的传导逻辑
Python列表存储的是对象引用,而非对象本身的数值快照:
- 第一次执行
theta_list.append(theta)时,列表第一个元素和初始theta完全指向同一块内存地址。 - 后续循环中每次用增强赋值更新theta时,是直接修改这块共享内存里的数值,从未生成新的数组对象。
- 后续循环每次执行
theta_list.append(theta)时,本质都是把同一个内存地址的引用反复存入列表。 - 最终所有列表元素都指向被反复修改、最后留存收敛终值的同一块内存,打印时自然全部显示为最终theta的数值,没有历史迭代的变化过程。
替换为普通赋值后正常的原因
普通赋值每轮迭代都会生成独立的新数组空间,theta每轮更新都会绑定到新的内存块。这时候存入列表的每一个引用,对应独立的、不会被后续操作修改的内存块,自然能正确留存每一轮迭代的theta快照。
兼容增强赋值的修正方案
如果希望保留增强赋值的内存效率优势,只需要在存入列表时生成独立的数值拷贝,将对应append语句修改为:theta_list.append(theta.copy())
即可在不改动参数更新逻辑的前提下,正确记录每轮的历史值。
内容的提问来源于stack exchange,提问作者antelk
相关产品推荐
相关产品推荐

