Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何找到id相同的所有变量?_Python_Arrays_Numpy_Copy - Fatal编程技术网

Python 如何找到id相同的所有变量?

Python 如何找到id相同的所有变量?,python,arrays,numpy,copy,Python,Arrays,Numpy,Copy,假设我有一个numpy数组a,然后像这样创建b: a = np.arange(3) b = a 如果我现在更改b例如这样 b[0] = 100 并打印a、b、它们的ids和.flags print a print a.flags print b print b.flags print id(a) print id(b) 我得到 [100 1 2] C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : True

假设我有一个
numpy
数组
a
,然后像这样创建
b

a = np.arange(3)
b = a
如果我现在更改
b
例如这样

b[0] = 100
并打印
a
b
、它们的
id
s和
.flags

print a
print a.flags    
print b
print b.flags
print id(a)
print id(b)
我得到

[100   1   2]

  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

[100   1   2]

  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

139767698376944
139767698376944
因此,
a
b
看起来相同,它们的
id
s与预期相同

当我现在使用
copy()

我明白了

在这种情况下,
c
d
不同,它们的
id
s也不同;正如所料

然而,让我困惑的是我从
.flags
获得的输出:在所有情况下,
OWNDATA
都设置为
True
。当我读这本书时,我发现:

OWNDATA(O)阵列拥有其使用或借用的内存 另一个物体

我现在的主要问题是:

查找指向相同id的所有变量(在上例中为
a
b
)的最简单方法是什么,即检查是否存在具有相同id的另一个变量?我想,
OWNDATA
会有帮助,但显然不是

相关问题:


实际使用的
OWNDATA
是什么,在这种情况下
OWNDATA
设置为
False

赋值
b=a
不会在原始数组
a
上创建视图,而只是创建对它的引用。换句话说,
b
只是
a
的不同名称。变量
a
b
都指向拥有其数据的同一数组,因此设置了
OWNDATA
标志。修改
b
将修改
a

赋值
b=a.copy()
创建原始数组的副本。也就是说,
a
b
指各自拥有数据的单独数组,这样就设置了
OWNDATA
标志。修改
b
不会修改
a

但是,如果进行赋值
b=a[:]
,则将创建原始数组的视图,并且
b
将不拥有其数据。修改
b
将修改
a


这个函数就是你要找的。它按照框中的说明执行:检查数组
a
b
是否共享内存,从而相互影响。

赋值
b=a
不会在原始数组
a
上创建视图,而只是创建对它的引用。换句话说,
b
只是
a
的不同名称。变量
a
b
都指向拥有其数据的同一数组,因此设置了
OWNDATA
标志。修改
b
将修改
a

赋值
b=a.copy()
创建原始数组的副本。也就是说,
a
b
指的是各自拥有数据的独立数组,因此设置了
OWNDATA
标志。修改
b
不会修改
a

但是,如果进行赋值
b=a[:]
,则将创建原始数组的视图,并且
b
将不拥有其数据。修改
b
将修改
a


这个函数就是你要找的。它按照框中的说明执行:检查数组
a
b
是否共享内存,从而相互影响。

有两个问题-如何确定要比较的变量,以及如何比较它们

先拿第二个

我的版本(1.8.2)没有
np.共享内存
功能。它确实有一个
np。可以共享内存

是添加
共享\u内存的拉取请求
;日期是去年八月。因此,您必须使用全新的
numpy
。注意,最终测试可能很难,并且可能会发出“太难”的错误消息。例如,我想象有一些片共享内存,但很难通过简单地比较缓冲区起始点来识别

是这些
内存重叠
功能的单元测试。如果您想了解考虑两个已知阵列之间所有可能的重叠情况是一项多么艰巨的任务,请阅读本手册

我想看一下数组的
。\uuuuuuuuuuuuuuuuuuuuu接口。该字典中的一项是“data”,它是指向数据缓冲区的指针。相同的指针表示数据是共享的。但是一个视图可能会从某个地方开始。如果
shares\u memeory
看到这个指针,我不会感到惊讶

相同的
id
表示两个变量引用同一个对象,但不同的数组对象可以共享一个数据缓冲区

所有这些测试都需要寻找特定的参考资料;所以你仍然需要得到一些参考文献的列表。查看
locals()
?,
globals()
。对于未命名的引用,例如数组列表或一些用户定义的字典,该怎么办

Ipython运行的一个示例:

一些变量和参考:

In [1]: a=np.arange(10)
In [2]: b=a           # reference
In [3]: c=a[:]        # view
In [4]: d=a.copy()    # copy
In [5]: e=a[2:]       # another view
In [6]: ll=[a, a[:], a[3:], a[[1,2,3]]]  # list 
比较
id

In [7]: id(a)
Out[7]: 142453472
In [9]: id(b)
Out[9]: 142453472
除了
ll[0]
之外,其他人都不共享
id

In [10]: np.may_share_memory(a,b)
Out[10]: True
In [11]: np.may_share_memory(a,c)
Out[11]: True
In [12]: np.may_share_memory(a,d)
Out[12]: False
In [13]: np.may_share_memory(a,e)
Out[13]: True
In [14]: np.may_share_memory(a,ll[3])
Out[14]: False
这正是我所期望的;视图共享内存,副本不共享

In [15]: a.__array_interface__
Out[15]: 
{'version': 3,
 'data': (143173312, False),
 'typestr': '<i4',
 'descr': [('', '<i4')],
 'shape': (10,),
 'strides': None}
In [16]: a.__array_interface__['data']
Out[16]: (143173312, False)
In [17]: b.__array_interface__['data']
Out[17]: (143173312, False)
In [18]: c.__array_interface__['data']
Out[18]: (143173312, False)
In [19]: d.__array_interface__['data']
Out[19]: (151258096, False)            # copy - diff buffer
In [20]: e.__array_interface__['data'] 
Out[20]: (143173320, False)            # differs by 8 bytes
In [21]: ll[1].__array_interface__['data']
Out[21]: (143173312, False)            # same point
其他测试也一样

我可以用同样的方法搜索
ll

In [28]: [n for n,l in enumerate(ll) if id(l)==id(a)]
Out[28]: [0]
我可以在
locals()
搜索中添加一个层,通过测试一个项目是列表还是字典,并在其中进行搜索

因此,即使我们确定了测试方法,搜索所有可能的引用也不是一件小事

我认为最好的方法是只了解您自己对变量的使用,这样您就可以清楚地识别引用、视图和副本。在选定的情况下,您可以执行测试,如
可以共享内存
或比较数据缓冲区。但是没有一个便宜的、确定的测试。当在
In [15]: a.__array_interface__
Out[15]: 
{'version': 3,
 'data': (143173312, False),
 'typestr': '<i4',
 'descr': [('', '<i4')],
 'shape': (10,),
 'strides': None}
In [16]: a.__array_interface__['data']
Out[16]: (143173312, False)
In [17]: b.__array_interface__['data']
Out[17]: (143173312, False)
In [18]: c.__array_interface__['data']
Out[18]: (143173312, False)
In [19]: d.__array_interface__['data']
Out[19]: (151258096, False)            # copy - diff buffer
In [20]: e.__array_interface__['data'] 
Out[20]: (143173320, False)            # differs by 8 bytes
In [21]: ll[1].__array_interface__['data']
Out[21]: (143173312, False)            # same point
In [26]: [(k,v) for k,v in locals().items() if id(v)==id(a)]
Out[26]: 
[('a', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])),
 ('b', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))]
In [28]: [n for n,l in enumerate(ll) if id(l)==id(a)]
Out[28]: [0]
In [35]: a.flags['OWNDATA']
Out[35]: True
In [36]: b.flags['OWNDATA']   # ref
Out[36]: True
In [37]: c.flags['OWNDATA']   # view
Out[37]: False
In [38]: d.flags['OWNDATA']   # copy
Out[38]: True
In [39]: e.flags['OWNDATA']   # view
Out[39]: False
In [40]: np.arange(3).flags['OWNDATA']
Out[40]: True
In [41]: np.arange(4).reshape(2,2).flags['OWNDATA']
Out[41]: False
temp = np.arange(4); temp = temp.reshape(2,2)
temp = np.arange(4); temp.shape = (2,2)