def f(x, y):
x.append(x.pop(0))
x.append(y[0])
return x
a = [4,5]
b = [1,2,3]
w = f(a,b) + f(a,b)
w原来是[4,1,5,1,4,1,5,1]然而如果我手动完成代码(在我脑海中),我得到[5,4,1,4, 1,5,1]
为什么会这样?
f(a,b)= [5,4,1]对吗?所以a则为= [5,4,1],b = [1,2,3]。
那么f(a,b)= [4,1,5,1]这将是: [5,4,1] + [4,1,5,1] = [5,4,1,4,1,5,1]不[4,1,5,1,4,1,5,1 ]
为什么代码会改变这个?在尝试自己运行代码时,我做错了什么?
答案 0 :(得分:6)
两个调用都返回相同的列表,即绑定到a
的对象,从而导致第二个返回值(仍然是绑定到a
的对象)被添加到本身。该函数只改变列表,永远不会替换它。
答案 1 :(得分:3)
您的问题是您的代码都会更改原始列表,尽管会返回对它的引用。当您第二次调用 f 时(从不使用单字母名称!!!),您也可以更改原始调用的结果。让我们分阶段做:
n [53]: a1 = f(a,b)
In [54]: a
Out[54]: [5, 4, 1]
In [55]: a2 = f(a,b)
In [56]: a2
Out[56]: [4, 1, 5, 1]
In [57]: a
Out[57]: [4, 1, 5, 1]
这说明了我的观点(函数 id 返回对象的引用)
In [77]: id(a)
Out[77]: 145114860
In [78]: id (f(a,b))
Out[78]: 145114860
如您所见,您的功能有副作用。如果你像这样重写它
def f(x, y):
x.append(x.pop(0))
x.append(y[0])
return copy(x)
第二个电话不会影响第一个电话的结果 -
In [74]: id(a)
Out[74]: 145114860
In [75]: id (f(a,b))
Out[75]: 145113356
,结果为[5,4,1,4,1,5,1]
答案 2 :(得分:0)
f(a,b)= [5,4,1]对吗?所以那么a将是= [5,4,1]和b = [1,2,3]。
一切正确。然而。如果你看看f
正在做什么,它只是返回变异的x
(即变异a
)。所以这样做两次:
f(a,b)
Out[40]: [5, 4, 1]
a
Out[41]: [5, 4, 1]
f(a,b)
Out[42]: [4, 1, 5, 1]
a
Out[43]: [4, 1, 5, 1]
然后将其与自身连接起来。在w
两次变异之后,这就是a + a
:a
。