为什么这个.pop(0)像这样工作

时间:2013-11-07 05:18:43

标签: python python-2.7

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 ]

为什么代码会改变这个?在尝试自己运行代码时,我做错了什么?

3 个答案:

答案 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 + aa