Python:理解引用

时间:2013-05-21 16:49:01

标签: python numpy

我理解基本的python引用,比如a + = b和a = a + b之间的区别,但这让我感到困惑。

import numpy as np
arr1 = np.arange(6).reshape(2,3)
arr2 = arr1[0]
arr2 is arr1[0] #returns False, when I expect True
arr1[0] = [7,8,9]
arr2 #[7,8,9], when I expect [0,1,2] since the 'is' returned False

这里发生了什么?

5 个答案:

答案 0 :(得分:8)

索引numpy数组时,会创建一个新视图(它本身就是一个numpy数组)。这是一个不同的对象,因此is失败了,但它是对同一块诚实实际硬件内存的看法。因此,修改该视图时,可以修改可能存在其他视图的内存位。

编辑:通过检查数组的ctypes.data属性,您实际上可以看到与numpy数组关联的内存的起始地址。

In [1]: import numpy as np

In [2]: arr1 = np.arange(6).reshape(2,3)

In [3]: arr2 = arr1[0]

In [4]: arr2.ctypes.data
Out[4]: 39390224

In [5]: arr1[0].ctypes.data
Out[5]: 39390224

同样的!

答案 1 :(得分:4)

如果需要检查两个numpy阵列是否指向相同的数据,请使用base属性。从你的例子:

>>> arr1 = np.arange(6).reshape(2,3)
>>> arr2 = arr1[0]
>>> arr1
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr1.base # arr1 is a view of the array before reshaping!
array([0, 1, 2, 3, 4, 5])
>>> arr2.base
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr2.base is arr1
True

从numpy 1.7 base开始一直钻到原始数组。从发行说明:

  

ndarrays上的.base属性,用于视图以确保   拥有内存的底层数组现在不会过早解除分配   当您拥有视图视图时折叠参考。例如::

a = np.arange(10)
b = a[1:]
c = b[1:]
  

在numpy 1.6中,c.basebc.base.basea。在numpy 1.7中,   c.basea

答案 2 :(得分:0)

您让is===运营商感到困惑。

  • is进行身份检查。使用它来查看两个变量是否实际指向同一对象而不仅仅具有相同的值
  • =是赋值运算符。它为变量(或切片,如您的情况)分配值。
  • ==相等运算符。它检查两个对象是否具有相同的语义值。

所以在你的情况下:

arr2 == arr[0] # now should return True

当您从数组中读取值时,Numpy似乎会创建新对象。因此,每次阅读时,都会创建一个新对象。因此,两个读取生成的对象不同,因此is会将False作为结果。

答案 3 :(得分:0)

>>> arr1 = np.arange(6).reshape(2,3)
>>> arr1
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr2 = arr1[0]
>>> arr2
array([0, 1, 2])

是的,arr1[0]arr2是平等的。然而,

>>> arr2 is arr1[0]
False

因为is不是比较ndarrays的工具。使用is,您可以检查arr1[0]arr2是否是同一个对象,而不是。尝试使用==,您将获得

>>> arr2 == arr1[0]
array([ True,  True,  True], dtype=bool)

或使用numpy.equal(t1,t2)

>>> np.equal(arr2, arr1[0])
array([ True,  True,  True], dtype=bool)

然后你想对你的相等测试有一个布尔答案,做

>>> (np.equal(arr2, arr1[0])).all()
True

答案 4 :(得分:0)

'is'运算符比较两个对象的身份; id()函数返回一个表示其身份的整数(当前实现为其地址)。

http://docs.python.org/2/reference/datamodel.html

例如,

a = 1, b = 1
a is b
Out[26]:True

id(a)
Out[27]:37470472L

id(b)
Out[27]:37470472L

id(1)
Out[27]:37470472L

这三个人都有相同的身份。但是,

a = [1]
b = [1]
a is b
Out[26]:False

id(a)
Out[37]:142781064L

id(b)
Out[38]:142780616L

因此,数组中也会发生同样的事情。他们没有相同的身份。

相关问题