您没有创建数组的副本。您只需创建对同一数组的新引用。如果要复制数组,请使用numpy.copy
:
y = numpy.copy(x)
请注意,使用常规 python 列表,您可以获得具有语法的浅表副本the_list[:]
(其中[:]
意味着创建一个从原始列表开头开始并在原始列表末尾结束的切片),而在大多数情况下,numpy
切片实际上是视图:
>>> import numpy as np
a>>> a = np.arange(10)
>>> b = a[:]
>>> b[0] = 100
>>> a
array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])
相对:
>>> a = range(10)
>>> b = a[:] # does a real copy
>>> b[0] = 100
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b
[100, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在 python 中,每个标识符都是对对象的引用。当你做作业时:
y = x
赋值将名称绑定y
到 引用的对象x
。换句话说,成为的引用的y
副本。现在被引用的对象又多了一个引用。当一个对象不再有引用时,它就会从内存中删除。Python 没有 C 中的“变量”概念。x
x
另一种思考方式是任何标识符都是指向对象的指针。因此y = x
复制指针而不是对象本身(这就是实际发生的情况。C/API 总是使用指向PyObject
结构的指针)
这在每个 python 教程中都有解释,因此我建议你先搁置numpy
一会,先阅读 python 教程。
我决定使用一些 Unicode 艺术来说明绑定会发生什么。这个想法不是我的,而是来自python-it.org 论坛的用户 Claudio_F 。
这个想法是在 python 中你有标识符,我将其表示为浮标。每个浮标都可以连接到一个物体,该物体被表示为海底的一块岩石(或其他任何东西)。一个物体可以绑定更多的浮标。当一个物体没有绑定任何浮标时,它就会沉入海中,当它到达海底时,一个巨大的海怪会摧毁它(又名垃圾收集器)。
现在当你做任务时:
a = 5
这是这种情况:
___
( )
( a )
( )
^~~~~^~~~~^~~'¿'~~~~^~~~~~^~~~~~^~~~~~~
|
O .--+--. o ___
| 5 | |\/ x\
.-----. ^\_/
___ O
o /o \/|
〉 GC | o o
\___/\|
(
) ) (
( ( ) ) )
( ) ) ) ( ( ( ( ) ( (
)( ( ( ( ) ) ) ) ( ) )
当你做任务时:
b = a
两个浮标都绑定到同一个对象:
___ ___
( ) ( )
( a ) ( b )
( ) ( )
^~~~^~~~~^~~'¿'~~~~~^~~~~^~~~~'¿'~~~~^~~~~~^
\ o /
\ o /
\ O /
\ / __________
\ / / \
o \ / / \
\ / ) | ( | )
O \ / ( | ) (
o \/ | ( )
.--+--. )
| 5 |
.-----.
___ O
o /o \/|
〉 GC | o o
\___/\|
(
) ) (
( ( ) ) )
( ) ) ) ( ( ( ( ) ( (
)( ( ( ( ) ) ) ) ( ) )
当你做第三个作业时:
a = 7
a
链条从物体上解开并5
绑定到一个新的7
, 物体上,但b
的浮标仍然绑定到5
:
___ ___
( ) ( )
( a ) ( b )
( ) ( )
^~~~^~~~~^~~'¿'~~~~~^~~~~^~~~~'¿'~~~~^~~~~~^
| o |
| |
| O | o
| |
o | |
| o |
| .--+--.
O .--+--. | 5 |
| 7 | .-----.
.-----.
o
___ O
o /o \/|
〉 GC | o o
\___/\|
(
) ) (
( ( ) ) )
( ) ) ) ( ( ( ( ) ( (
)( ( ( ( ) ) ) ) ( ) )
我希望你喜欢这些照片,并且他们清楚地说明了它是如何工作的。(水母和死鱼只是因为我觉得它们很酷而已)
顺便说一句,这种表示对于理解对象之间的引用也很棒。例如代码:
L = [1,2,3]
将像这样表示:
___
( )
( L )
( )
^~~~~^~~~~^~~~~'¿'~~~~^~~~~^~~~~^~~~~^
|
|
.--------+----------.
| [ '¿', '¿', '¿' ] |
.----|----|----|----.
/ | \
/ | \
.--+--. | .--+--.
| 1 | | | 3 |
.-----. | .-----.
|
.--+--.
| 2 |
.-----.
___ O
o /o \/|
〉 GC | o o
\___/\|
(
) ) (
( ( ) ) )
( ) ) ) ( ( ( ( ) ( (
)( ( ( ( ) ) ) ) ( ) )
请注意列表如何具有指向对象的“指针”,而不是实际对象。
另外,回到切片,如果你这样做:
R = L[:]
您获得此方案:
___ ___
( ) ( )
( L ) ( R )
( ) ( )
^~~~~^~~~~^~~~~'¿'~~~~^~~~~^~~~~^~~~~^~~~~'¿'~~~~~~^~~~~~^~~~~~
| |
| |
.--------+----------. .---------+---------.
| [ '¿', '¿', '¿' ] | | [ '¿', '¿', '¿' ] |
.----|----|----|----. .----|----|----|----.
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
\ | .--+--. | /
\ | | 1 | | /
\ | .-----. | /
\ \ / /
\ \ / /
\ \ / /
| \ / |
| .--+--. |
| | 2 | |
| .-----. |
\ /
\ /
\ /
\ /
.--+--.
| 3 |
.-----.
___ O
o /o \/|
〉 GC | o o
\___/\|
( (
) ) ( ) (
( ( ) ) ) ( ) ) ) (
( ) ) ) ( ( ( ( ) ( ( ) )( ( ( ( )(
)( ( ( ( ) ) ) ) ( ) ) ( ( ) ) ) ) ) ( )
请注意,两个列表都指向相同的对象。这就是为什么它被称为浅拷贝。如果你放了一些可变对象而不是整数,就像另一个列表一样,你可以清楚地理解为什么修改它会改变两个列表的内容。