正如标题所暗示的,我有一个关于更改集合中的对象以使它们变得完全相同(在集合中)的问题。只是好奇。
我问这个问题是关于 Python 的,但如果它可以概括,请随意这样做。
如果我在 Python 中理解正确的话 Set iterable 将通过使对象的哈希值相等来确定对象是否“相等”。所以对于对象 a 和 b 这将是:
hash(a) == hash(b)
对于您创建的任何对象,您都可以覆盖 standard hash function , __hash__
,根据您的具体喜好。
假设您创建了一个散列函数,该函数采用对象中的多个或所有对象,并将散列组合用作自己的散列组合(例如,通过对它们进行 OR 运算)。
现在,如果您在一个 Set 中有几个最初不同的对象,然后遍历该 Set 并更改其中的对象以使它们的内部对象匹配,那么该 Set 会发生什么?它们会全部留在那里,还是会被踢出,或者我们是否需要等到对 Set 执行操作?还是我们在某处引发了一些错误?
最佳答案
考虑这个测试:
class A:
def __init__(self, h):
self.h = h
def __hash__(self):
return self.h
x = A(1)
y = A(2)
a = {x, y}
print x in a, y in a
print a
print "----"
x.h = 2
print x in a, y in a
print a
结果:
True True
set([<__main__.A instance at 0x10d94fd40>, <__main__.A instance at 0x10d94fd88>])
----
False True
set([<__main__.A instance at 0x10d94fd40>, <__main__.A instance at 0x10d94fd88>])
如您所见,第一个对象 x
仍然存在,但 in
运算符报告它不存在了。为什么会这样?
根据我的理解,Set对象是使用哈希表实现的,而哈希表通常有这样的结构:
hash_value => list of objects with this hash value
another_hash_value => list of objects with this hash value
当 Set 响应 in
请求时,它首先计算参数的哈希值,然后尝试在相应的列表中定位它。我们的集合 a
最初是这样的:
1 => [x]
2 => [y]
现在,我们更改x
的散列并询问集合对象是否存在。该集合计算哈希值(现在是 2
)试图在第二个列表中定位 x
但失败了 - 因此 False
。
为了让事情变得更有趣,让我们做吧
a.add(x)
print x in a, y in a
print a
结果:
True True
set([<__main__.A instance at 0x107cbfd40>,
<__main__.A instance at 0x107cbfd88>,
<__main__.A instance at 0x107cbfd40>])
现在我们在集合中有两次相同的对象!如您所见,没有自动调整,也没有错误。 Python 是一种成人语言,它总是假定您知道自己在做什么。
关于python - 当 Set 中的对象被更改以相互匹配时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19953339/