In [1]: a = object()
In [1]: [a] * 10
Out [1]:
[<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>,
<object at 0x7f57d0670a90>]
2条答案
按热度按时间9jyewag01#
0
不可变。实际上,这并不是导致看似不同的行为的根本原因,真实的的区别在于,你不打算改变
0
的值(因为你不能改变),所以,如果你改变了其中一个的值(如果可能的话),你并不真正知道0
的值会不会改变。请注意,这与外部迭代相同。
第一个
在这里,您可以更改
T[0]
而不更改T[1]
。第一次
所以,如果改变
T[0][0]
也不会改变T[0][1]
,你不应该感到惊讶。如果说T[0][0]=5
仍然保持T[0][1]
为2,这里没有不同的行为。看起来不同的行为发生的地方是,您不是在更改
T[0]
,而是在更改其内容。但这不是一回事!你改变的是
T[0]
的内容,而不是T[0]
本身。因此,如果您想比较
outer
数组和内部数组的情况(这就是您的问题:为什么改变一列不会影响另一列。为什么改变T[0][0]
不会影响T[0][1]
),您应该与下面这样的操作进行比较这是一个不改变
T[0][0]
但改变其内容的操作,它改变了存储在T[0][0]
中的对象0
的值。如果这样的操作是可能的,那么你会看到
但是这样的操作是不可能的。因为
0
是不可变的。因此你不能执行类似于改变T[0]
的内容的操作。因此你不可能在两个操作之间有令人惊讶的行为差异,因为它们根本不是同一个操作。T[0][0]
改变了T[0]
的内容,但改变了T[0][0]
本身。简化问题
我知道前面的论证可能很难理解,因为
T[0]
有两个角色:它既是数组又是数组元素。因此,简化问题可能更容易。
你的问题可以归结为4种操作(包括1种不可能的操作):
您的问题是“为什么在操作1中只更改了一个元素,而在操作4中更改了所有元素”。
我的答案是,你在比较不同的东西。操作1(改变
T[0]
)与操作2相似。在操作2中,也只有一个元素发生了变化。操作4(改变
T[0]
的内容)与操作3类似。如果操作3是可能的。但它不是。因为整数是不可变的。如果它们不是,那么操作3将是可能的,然后你会看到,在这样的操作之后,所有的元素也会改变(即对同一元素的3个引用的所有值)回到你的例子:更改
T[0][0]
只是在数组T[0]
中执行的操作1,因此它不影响T[0]
的其他元素是正常的。您更改的不仅仅是T[0][0]
的内容。但是,从数组T
的Angular 来看,更改T[0][0]
也会更改T[0]
的内容。这与操作4类似。因此,它会影响同一数组的其他引用,即T[1]
和T[2]
,这是正常的。x7yiwoj42#
请参阅List of lists changes reflected across sublists unexpectedly
当列表相乘时,结果列表中的对象将是具有相同
id()
的相同示例。因此,[0] * width
(一个list
)将在所有行[0..height)
中共享。