【问题标题】:Python bitarray setPython 位数组集
【发布时间】:2015-06-25 20:06:45
【问题描述】:

生成一组类似位数组的对象的最佳方法是什么,以便我可以有效地测试成员资格。天真的方式似乎没有像我预期的那样工作:

>>> from bitarray import bitarray
>>> 
>>> bitarray_set = set([bitarray('0000'), bitarray('0001')])
>>> bitarray_set
set([bitarray('0001'), bitarray('0000')])
>>> 
>>> bitarray('0000') in bitarray_set
False

一种解决方法是保留一组单独的字符串或其他更友好的对象作为键。然后将位数组转换为字符串并针对该集合测试成员资格。但这似乎有点麻烦。有没有更好的解决方案?

【问题讨论】:

    标签: python set bitarray


    【解决方案1】:

    看来bitarray 没有保持哈希不变:

    >>> x = bitarray(b'0000')
    >>> y = bitarray(b'0000')
    >>> x == y
    True
    >>> hash(x) == hash(y)
    False
    

    这违反了__hash__ 的API,如documented

    唯一需要的属性是比较相等的对象具有相同的哈希值

    这意味着位数组实际上是不可散列的,并且不能在集合中或作为字典键可靠地工作。

    我认为这是位数组库中的一个错误。我以前从未听说过 bitarray,而且它似乎没有太多文档。据我所知,它甚至没有说明应该如何为位数组定义相等,也没有说明它们是否应该是可散列的,但它似乎以不兼容的方式实现了相等和散列。

    【讨论】:

    • 我认为您对这个问题的看法是正确的,但由于数组是可变的,可能它们不应该是可散列的,我们应该有bitarray.__hash__ = None 来防止它。
    • @DSM:是的,这是有道理的。就像我说的那样,从文档中不清楚应该是什么行为。但它们要么需要变得不可变,要么不可散列。
    猜你喜欢
    • 2020-05-10
    • 1970-01-01
    • 2017-10-02
    • 2017-01-27
    • 2021-01-01
    • 2016-05-31
    • 2012-08-11
    • 2019-09-09
    • 2015-07-06
    相关资源
    最近更新 更多