Python中while嵌套for循环内列表赋值异常问题咨询
问题分析:为什么修改V后V_origin的值也同步变化了?
首先先把你贴的代码整理成更易读的格式:
V = 16*[0.1] key = True i = 0 while key: delta = 0 V_origin = V for s in range(16): v = V[s] V[s] = V_origin[s] * 2 delta = max(delta,abs(v - V[s])) if delta < 0.01: key = False print(V, V_origin)
你的困惑完全合理——按直觉V_origin = V之后,它应该是V的一个“快照”,不会跟着V的修改而变化,但实际二者始终相同,问题出在Python对可变对象的赋值逻辑上:
- 在Python里,列表属于可变对象,当你执行
V_origin = V的时候,并没有创建一个新的列表副本,只是让V_origin这个变量指向了和V同一个列表对象(可以理解为给同一个内存里的列表起了第二个名字)。 - 所以当你在for循环里修改
V[s]的时候,本质上是在修改那个唯一的列表对象,V_origin作为指向它的另一个变量,自然也会看到修改后的结果。
你可以自己验证这个逻辑:在代码里加一行打印内存地址的代码,会发现两个变量指向的是同一个内存对象:
V = 16*[0.1] V_origin = V print(id(V), id(V_origin)) # 输出两个完全相同的数字,说明是同一个对象
那要怎么得到真正独立的V的副本呢?有几种常用方法:
- 使用列表切片:
V_origin = V[:],切片操作会创建一个新的列表,包含原列表的所有元素 - 使用
list()构造函数:V_origin = list(V) - 如果是嵌套列表这类复杂结构,需要用
copy模块的deepcopy,但这里是一维列表,前两种就足够了
修改后的代码示例:
V = 16*[0.1] key = True i = 0 while key: delta = 0 V_origin = V[:] # 改成切片创建独立副本 for s in range(16): v = V[s] V[s] = V_origin[s] * 2 delta = max(delta,abs(v - V[s])) if delta < 0.01: key = False print(V, V_origin)
这样运行后,你就能看到V和V_origin的值出现差异了——V是修改后的结果,V_origin保留了循环开始时V的初始状态。
内容的提问来源于stack exchange,提问作者exteral
相关产品推荐
相关产品推荐

