0

我在这里更新 x,如果我在更新 x 后打印 y,y 将显示反射。但是,在第一个示例中, y 没有显示出这种变化。这就是我迷路的地方。谁可以给我解释一下这个?

x = 2
y = x + 3
###  printing y will yield 5
x = 8    # ok am I updating the same storage space that x pointed to, or is abandoning it and creating
         # another with a value of 8?
###  printing y will still yield 5 (why is that? if Y always points to x and adds 3 to it?)

in contrast with this:

x = [1,2,3]
y = [x,4,5,6]
x[0] = 50
y[2] = 80
z = y[:] + [100,101,1020
4

7 回答 7

4

x = 2 创建了一个值为 2 的新对象,x 引用它

y = x + 3 创建了一个值为 5 的新对象,y 引用它

x = 8创建了一个值为 8 的新对象,现在 x 引用它。值为 2 的对象的引用计数递减,并且是垃圾回收的候选对象。

x = [1,2,3] 创建了一个新列表(“类型/类列表的对象”),并且 x 引用它。

y = [x,4,5,6] 创建了一个新的列表对象,并且 y 引用它。前面x提到的对象基本没有了。它是所谓的“垃圾”,可能会被所谓的“垃圾收集器”收集。

x[0] = 50 将 x 引用的列表的第一个元素更改为 50

y[2] = 80 将 y 引用的列表的第三个元素更改为 80

z = y[:] 创建了一个新的列表对象,其中包含 y 引用的元素的副本。这不会复制第一个元素中的引用 (x)。看copy.deepcopy()那个。

于 2012-10-12T13:15:04.413 回答
1

你写了:

打印 y 仍然会产生 5(这是为什么呢?如果 Y 总是指向 x 并添加 3?)

你的误解从这里开始。y指向x。y值为 5。听起来您几乎试图将其与单元格可以包含公式的电子表格模型等同起来。编码不是那样的。当你给 赋值时y,你是在赋值,而不是公式。

于 2012-10-12T12:59:19.257 回答
0
y = x + 3

y 的值会立即计算出来。就这样。

于 2012-10-12T13:21:48.133 回答
0

让我们以您的示例为例,并替换变量:

原来的:

x = 2
y = x + 3
###  printing y will yield 5
x = 8    # x now holds the value of 8 instead of 2
###  printing y will still yield 5 (why is that? if Y always points to x and adds 3 to it?)

in contrast with this:

x = [1,2,3]
y = [x,4,5,6]
x[0] = 50

替换:

x = 2
y = 2 + 3
###  printing y will yield 5
x = 8    
###  printing y will still yield 5 because it is set to 2+3


x = [1,2,3] 
y = [[1,2,3],4,5,6] #[1,2,3] is the same list as x
x[0] = 50 # x still holds the value of the same list, 
#however you're changing the value of the first element of the, 
#you're not changing x itself though.

在第一个示例中,您正在更改 x 本身的值。在第二个中,您将更改 x 的属性,同时将 x 保留为相同的值。

于 2012-10-12T13:13:58.177 回答
0

如果你真的想要这种行为,你必须使用一个函数:

>>> x = 2
>>> y = lambda: x + 3
>>> y()
5
>>> x = 8
>>> y()
11

因为 x 是不可变的,所以赋值总是会创建不会反映未来变化的新对象。

于 2012-10-12T13:09:33.260 回答
0

当您使用=带有变量名称的运算符作为左侧值时,这会将左侧的名称绑定(或重新绑定)到右侧的对象。y = x + 3用valuey引用一个对象,然后让变量 x用 value 引用一个对象。int5x = 8int8

左边是这样的x[0],你正在做项目分配,只改变第 0 个项目x;该名称x仍指原始列表,该列表也是 指向的列表的成员y

于 2012-10-12T12:57:04.517 回答
0

把它想象成一组盒子。当我们谈论单个变量而不是数组时,X 是一个框的名称,y 也是如此。所以 x = 2 表示将 2 放入标有 x 的框中。y = x + 3 表示将 x 中的内容加到 x 上,然后将其放入 y 中。x = 8 表示将框 x 中的内容替换为 8。y 已经计算好,因此无法更改。

对于像 x = [1, 2, 3] 这样的数组,x 不是指一个盒子,而是指一组盒子。它就像 x 指的是框 1、2 和 3,它们中的每一个都恰好具有值 1 2 和 3。因此,如果我更改列表 x 中第一个框的内容,则 x 本身未更改,它仍然是框列表 - 其中一个框的值已更改。y 在这种情况下是一个盒子列表,其中第一个不是真正的盒子,而是包含指向另一组盒子的指针。

于 2012-10-12T12:58:59.060 回答