Python 将元素追加到列表中:已追加的元素会随着时间的推移而毫无原因地发生更改

Python 将元素追加到列表中:已追加的元素会随着时间的推移而毫无原因地发生更改,python,Python,定义了一个接受两个元素列表作为参数的函数。我想通过将列表绘制到图形中来跟踪列表在使用函数进行迭代时是如何随时间变化的。但奇怪的事情发生了。只绘制了一个点,因此我尝试通过打印列表对其进行调试,如以下代码所示: from math import pi, sin, cos, tan import numpy as np alpha = pi/3 N = 10 def vmap(v): if v[0] >= 2*v[1]**0.5*tan(alpha)-(1-v[1])**0.5:

定义了一个接受两个元素列表作为参数的函数。我想通过将列表绘制到图形中来跟踪列表在使用函数进行迭代时是如何随时间变化的。但奇怪的事情发生了。只绘制了一个点,因此我尝试通过打印列表对其进行调试,如以下代码所示:

from math import pi, sin, cos, tan
import numpy as np


alpha = pi/3
N = 10


def vmap(v):
    if v[0] >= 2*v[1]**0.5*tan(alpha)-(1-v[1])**0.5:
        v[0], v[1] = v[0] - 2*v[1]**0.5*tan(alpha), v[1]
    else:
        z = v[1]
        v[1] = -v[1]*(1+0.5*sin(4*alpha)*tan(alpha))-0.5*v[0]**2*sin(4*alpha)/tan(alpha) + v[0]*v[1]**0.5*sin(4*alpha) + 2*(cos(alpha))**2
        v[0] = -v[0] + (z**0.5 - v[1]**0.5)*tan(alpha)
    return v

v = [0.3, 0.5]

v_list = []
print(v)
v_list.append(v)
print(v_list)
print(vmap(v))
v_list.append(vmap(v))
print(v_list)
输出:

[0.3, 0.5]
[[0.3, 0.5]]
[0.12389232074709905, 0.21378826929126177]
[[-0.41955313380287024, 0.40078051892442046], [-0.41955313380287024, 0.40078051892442046]]

我不明白发生了什么事。我在空列表中添加了
[0.3,0.5]
,空列表变成了
[[0.3,0.5]]
。但正如我在列表中添加的
vmap([0.3,0.5])
,即
[0.12389232074709905,0.2137882692126177]
,该列表不会产生
[[0.3,0.5],[0.12389232074709905,0.2137888269126177]
,但
[-0.41955313380287024,0.40078051892442046],-0.419583808080892446]的预期结果
这是凭空出现的。为什么会这样?

在调用
vmap
的过程中,您正在更改
v
。将
v
添加到
v_列表
时,会添加对
v
的引用。当您将
v
传递给函数
vmap
时,您正在对同一对象进行操作。在函数调用返回后,您在函数中对其所做的任何更改都会反映出来。

您正在将调用中的
v
更改为
vmap
。将
v
添加到
v_列表
时,会添加对
v
的引用。当您将
v
传递给函数
vmap
时,您正在对同一对象进行操作。您在函数内对其所做的任何更改都会在函数调用返回后反映出来。

仔细查看您的代码:您已经在v\u列表中添加了两次
v
。这不是两个单独的列表,而是同一个列表,两次。
v_list
的两个元素都是对
v
的引用:当您更改
v
时,每个引用的值都会更改

通过附加一个
v
的副本而不是您不断变化的变量来更改此设置:

from copy import copy
...
v_list.append(copy(v))
print(v_list)
print(vmap(v))
v_list.append(copy(vmap(v)))
print(v_list)
输出:

[0.3, 0.5]
[[0.3, 0.5]]
[0.12389232074709916, 0.2137882692912617]
[[0.3, 0.5], [-0.41955313380287046, 0.40078051892442046]]

仔细查看您的代码:您已经在v_列表中添加了两次
v
。这不是两个单独的列表,而是同一个列表,两次。
v_list
的两个元素都是对
v
的引用:当您更改
v
时,每个引用的值都会更改

通过附加一个
v
的副本而不是您不断变化的变量来更改此设置:

from copy import copy
...
v_list.append(copy(v))
print(v_list)
print(vmap(v))
v_list.append(copy(vmap(v)))
print(v_list)
输出:

[0.3, 0.5]
[[0.3, 0.5]]
[0.12389232074709916, 0.2137882692912617]
[[0.3, 0.5], [-0.41955313380287046, 0.40078051892442046]]

@佐藤,以下是你通常应该做的:

v = [0.3, 0.5]

v_list = []
print(v)
v_list.append(v)
print(v_list)
print(vmap(v))
v_list.append(v)  #Note that the function vmap modifies v
print(v_list)

@佐藤,以下是你通常应该做的:

v = [0.3, 0.5]

v_list = []
print(v)
v_list.append(v)
print(v_list)
print(vmap(v))
v_list.append(v)  #Note that the function vmap modifies v
print(v_list)

Python不会创建您期望的隐式副本。请继续阅读。一般来说,要么修改参数并返回
None
,要么返回一个新对象,保持参数不变。不要变异并返回参数。Python不会创建您期望的隐式副本。请继续阅读。一般来说,要么修改参数并返回
None
,要么返回一个新对象,保持参数不变。不要变异并返回参数。