python - 当 Set 中的对象被更改以相互匹配时会发生什么?

标签 python hash set

正如标题所暗示的,我有一个关于更改集合中的对象以使它们变得完全相同(在集合中)的问题。只是好奇。

我问这个问题是关于 Python 的,但如果它可以概括,请随意这样做。

如果我在 Python 中理解正确的话 Set iterable 将通过使对象的哈希值相等来确定对象是否“相等”。所以对于对象 ab 这将是:

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/

相关文章:

python - 是否可以预编译整个 python 包?

python - 如何从 Python 中的二维散点图数据创建热图?

Python - 如何获取在我的计算机上运行的服务

c - 尝试将哈希函数转换为 C

Ruby Hash 初始化(默认值 nil)

c++ - 用于整数下限和上限查询的快速数据结构?

python - Pandas to_datetime : Unknown string format

java - "contains"哈希集方法问题 (Java)

c# - 使用什么算法来检查一组是否与另一组重叠?

php - 使用 SHA-256 进行 CodeIgniter 哈希