在编写一些涉及numpy的程序时,我发现成员资格测试对numpy dtype对象没有预期效果。具体而言,set
的结果是意料之外的,但不是list
或tuple
。
import numpy as np
x = np.arange(5).dtype
y = np.int64
print(x in {y}, x in (y,), x in [y])
结果为False True True
。
在Python 2.7和3.6中都发现了这一点,安装了numpy 1.12.x。
知道为什么吗?
更新
看起来dtype对象不尊重Python中关于散列的一些假设。
http://www.asmeurer.com/blog/posts/what-happens-when-you-mess-with-hashing-in-python/
和https://github.com/numpy/numpy/issues/5345
谢谢@ ser2357112和@Fabien
答案 0 :(得分:2)
dtype对象的__hash__
和__eq__
实现非常糟糕。在其他问题中,__hash__
和__eq__
实现彼此不一致。你在这里看到了它的影响。
dtype __hash__
和__eq__
的其他一些问题是
__hash__
和__eq__
的方式可变的,这对于可散列对象永远不应该是真实的。 (具体来说,您可以重新分配结构化dtype的names
。)x
和y
,我们有x == y
和x == 'int64'
,但y != 'int64'
。__eq__
在应该返回TypeError
时会引发NotImplemented
。您可以提交错误报告,但查看与这些方法相关的existing bug reports,不太可能修复。设计过于混乱,人们已经依赖于破碎的部分。
答案 1 :(得分:0)
区别在于sets
如何在Python中实现in
关键字。
列表只是检查每个对象,检查是否相等。设置第一个哈希对象。
这是因为套装必须保证唯一性。但是你的对象并不等同:
>>> x
dtype('int64')
>>> y
<class 'numpy.int64'>
散列它们可能会产生不同的结果。