我正在阅读 SymPy 1.13.0 发行说明,这时一个条目引起了我的注意(强调我的):
的哈希函数和涉及 Float 的表达式现在遵循哈希不变量:ifFloats
then
a == b
。这确保了可以在 Python 的核心
hash(a) == hash(b)
和
set
数据结构中以有保证的确定性方式使用此类表达式。 但是,不建议将 sympy
dict
对象与非 sympy 数字类型(例如核心 Python 的Basic
或
float
)混合在同一个
int
中。
set/dict
我将 Python 的数字与 SymPy 的数字混淆在一组中,我无法解释发生了什么(sympy 1.13.0)。
我认为集合中的元素都有不同的哈希值。例如,在下面的代码块中有 4 个字符串,
a, b, c1, c2
。它们是内存中不同的对象。但是,c1
等于 c2
,因此它们具有相同的哈希值。因此,正如预期的那样,set([a, b, c1, c2])
仅包含三个元素:
a, b = "a", "b"
c1 = "This is a test"
c2 = "This is a test"
t = [a, b, c1, c2]
print("ids:", ", ".join([str(id(e)) for e in t]))
print("hashes:", ", ".join([str(hash(e)) for e in t]))
s = set(t)
print(s)
# hashes: -8635426522778860779, 3774980000107278733, 3487163462126586929, 3487163462126586929
# ids: 11791568, 11792624, 135187170594160, 135187170598448
# {'This is a test', 'a', 'b'}
在下面的示例中,内存中有三个不同的对象,
n1, n2, n3
。它们都生成相同的哈希值。我预计结果集仅包含一个元素。相反,它包含两个元素,显然共享相同的哈希值。
from sympy import *
n1 = 2.0
n2 = Float(2.0)
n3 = Float(2.0, precision=80)
t = [n1, n2, n3]
print("ids:", ", ".join([str(id(e)) for e in t]))
print("hashes:", ", ".join([str(hash(e)) for e in t]))
s = set(t)
print(s)
# ids: 135913432385776, 135912654307472, 135912654307632
# hashes: 2, 2, 2
# {2.0, 2.0000000000000000000000}
发生什么事了?
这两个元素根本不相等。