Python:为什么这是执行时的输出?

时间:2013-08-09 16:42:32

标签: python list copy

在我运行下面的代码之后,有人可以告诉我为什么这些是变量现在引用的值:

x = [1, 2, 3, 5] 
x1 = [1, 2, 3, 5] 
x2 = [1, 2, 3] 
y = [1, 2, 3] 
y1 = [1, 2, 3] 
y2 = [1, 2, 3]

为什么不是y = [1, 2, 3, 5]

为什么不是x1 = [1, 2, 3]

因为,遵循这个逻辑:

a = 1
b = a
a = 3
b is still equal to 1, not 3.

代码如下。谢谢你的帮助。

def my_function(x, y):
    x.append(5)
    y = y + [5]


x = [1, 2, 3]
x1 = x
x2 = x[:]


y = [1, 2, 3]
y1 = y
y2 = y[:]


my_function(x, y)

4 个答案:

答案 0 :(得分:5)

声明:

x1 = x

创建x指向的同一列表的引用副本。现在您将x传递给函数,在该函数中将值附加到x

x.append(5)

这将影响函数外部原始x指向的列表,并最终反映x1的修改。因此x1[1, 2, 3, 5]


现在,在y1的情况下,唯一的区别是函数中的这一行:

y = y + [5]

此行不会更改函数外部y引用的原始列表。它会创建一个局部变量y,并将其初始化为[1, 2, 3, 5]。但它不会更改函数外部y引用的原始列表,因此不会更改y1的列表。因此,y1y仍为[1, 2, 3]


您可以通过检查函数内部列表的id和外部列表来验证它:

>>> def my_function(x, y):
...     x.append(5)
...     y = y + [5]
...     return x, y   
... 
>>> 
>>> x = [1, 2, 3]
>>> x1 = x
>>> y = [1, 2, 3]
>>> y1 = y
>>> 
>>> x2, y2 = my_function(x, y)
>>> 
>>> id(x2) == id(x)   
True
>>> id(y2) == id(y)
False

因此,很明显原始id的{​​{1}}与从函数返回的x相同。但原始id的{​​{1}}与返回的y不同。

答案 1 :(得分:0)

简单。可变对象(如列表)通过引用传递,而不可变对象(如整数)通过值传递。

当您执行x1 = x时,x1会引用x;因此,对x的任何更改也适用于x1,因为它们指的是同一个对象x.append(5)通过引用更改原始x,从而更改x1

但是,当您执行x2 = x[:]时,您将通过切片来复制列表的内容。因此,您正在制作列表。

执行y = y + [5]时,您将在函数范围内创建新列表。因此,全局y(和y1引用)保持不变。 y2只是原始y的副本,因此该功能根本不会影响它。

答案 2 :(得分:0)

您实际上没有更改y的引用,只是将其设置为不同的引用。这实际上不会改变你传入的y。只是my_function的局部范围中的y。

逐步完成here

答案 3 :(得分:-1)

你实际上是在处理范围问题。起初看起来你会遇到别名问题,但是你传入的变量的重新定义只能在函数中持续存在。函数完成运行后,传入的参数(简单地说)将返回其原始值。只有在功能范围内,他们才会继续拥有您重新分配给它们的值。尝试在函数结束前打印奇数输出。