确定python对象之间的差异

时间:2018-11-01 12:08:59

标签: python equality

假设我有

tup1 = ((100,), (100,))
tup2 = tuple(map(tuple, np.array([100, 100]).reshape(-1,1)))

现在tup1 == tup2返回True(我意识到这来自结构相等)。

但是,作为某些python项目的一部分,我正在尝试执行以下操作:

from comtypes.automation import (byref, windll, 
    POINTER, VARIANT, PyDLL, py_object, wintypes)

_dll = PyDLL(pythoncom.__file__) 
_pack = _dll.PyCom_VariantFromPyObject
_pack.argtypes = py_object, POINTER(VARIANT) 
_pack.restype = wintypes.BOOL

现在

_pack(tup1, VARIANT())

同时工作

_pack(tup2, VARIANT())

引发异常。 tup1tup2在实际上有什么不同(除了指向内存中的不同地址)会导致这种情况

2 个答案:

答案 0 :(得分:5)

每种类型的对象都可以用自己的术语定义相等性。当元组具有相同的长度并且它们的 contents 被测试为相等时,它们是相等的。内容测试相等,因为两者都是元组,配对时每个测试也相等。

但是,虽然嵌套元组中的整数值测试相等,但它们的类型不是同一类型。整数测试数值是否相等,因此1 == 1.0也是正确的,即使一个对象是整数,另一个对象也是浮点数。同样,tup1[0][0] == tup2[0][0]是正确的,因为双方具有相同的数值100。

虽然第一个元组具有Python int对象,但第二个元组却没有。相反,您在这里有一个 numpy特定的整数类型

>>> import numpy as np
>>> tup2 = tuple(map(tuple, np.array([100, 100]).reshape(-1,1)))
>>> tup2[0][0]
100
>>> type(tup2[0][0])
<class 'numpy.int64'>

这很难看,因为值的表示形式与Python int类型完全相同,但是对于您正在进行的特定C API调用,numpy.int64不能识别为可接受的类型。

您需要将这些int64对象转换回标准的Python整数:

>>> int(tup2[0][0])
100
>>> type(int(tup2[0][0]))
<class 'int'>

如果您使用array.tolist(),实际上可以告诉numpy数组为您执行此操作:

>>> np.array([100, 100]).reshape(-1,1).tolist()
[[100], [100]]
>>> type(np.array([100, 100]).reshape(-1,1).tolist()[0][0])
<class 'int'>

摘自array.tolist()文档:

  

将数组数据的副本作为(嵌套的)Python列表返回。 数据项将转换为最兼容的Python类型。

(强调粗体的人)。

从那里创建元组:

tup2 = tuple(map(tuple, np.array([100, 100]).reshape(-1,1).tolist()))

尽管.tolist()为您提供了Python类型等效项的(嵌套)列表结构,但是如果您需要从现有数组中有效访问此类值,也可以使用numpy.item() method获得单个值

答案 1 :(得分:1)

tup1 == tup2可能是正确的,但是类型不同。尝试以下方法并说服自己:

[[type(dt) for dt in t] for t in tup1]

[[type(dt) for dt in t] for t in tup2]