【问题标题】:Unordered collection for unhashable objects?不可散列对象的无序集合?
【发布时间】:2012-01-10 02:07:09
【问题描述】:

我有一个字典,其中一些值是不可散列的。我需要一些方法来比较这两个无序组,以确保它们包含相同的元素。我不能使用列表,因为列表相等性考虑了顺序,但集合不起作用,因为 dicts 不可散列。我浏览了python文档,唯一看起来有用的是dict的视图,它在某些情况下是可散列的,但在这种情况下,这也无济于事,因为其中一个值是一个包含列表本身的对象,这意味着字典的视图也不会是可散列的。

对于这种情况是否有一个标准容器,或者我应该只使用列表并遍历两个列表中的每个元素并确保另一个列表中的某处有一个相等的元素?

【问题讨论】:

  • 我也遇到过类似的情况,我将 dict 复制到一个临时排序列表中,只是为了进行比较。尺寸或其他考虑因素可能会或可能不会使这成为您案例的好选择。
  • 究竟是什么让它们不可散列?如果它们不是可散列的,那么您究竟如何比较它们的相等性?
  • @Karl 字典中的值之一是一个列表。

标签: python collections


【解决方案1】:

我认为最简单的方法是使用列表。

group_1 = my_dict_1.values()
group_2 = my_dict_2.values()

您的比较不会像顺序重要,或者值是否可散列那么简单,但以下应该有效:

def contain_the_same(group_1, group_2):
    for item in group_1:
        if item not in group_2:
            return False
        else:
            group_2.pop(group_2.index(item))
    if len(group_2) != 0:
        return False
    return True

这应该能够很好地处理不可散列的对象:

>>> contain_the_same([1,2,3], [1,2,3])
True
>>> contain_the_same([1,2,3], [1,2,3,4])
False
>>> contain_the_same([1,2,[3,2,1]], [1,2,[3,2,1]])
True
>>> contain_the_same([5,1,2,[3,2,1,[1]]], [1,[3,2,1,[1]],2,5])
True

警告:如果一个列表中有重复项,则返回 false,而另一个则没有。如果您想将其设为允许的情况,则需要进行一些修改。

编辑:更简单:

sorted(my_dict_1.values()) == sorted(my_dict_1.values())

它甚至看起来比我的 contain_the_same 函数快两倍:

>>> timeit("contain_the_same([5,1,2,[3,2,1,[1]]], [1,[3,2,1,[1]],2,5])", 
           "from __main__ import contain_the_same", number=10000)/10000
8.868489032757054e-06
>>>timeit("sorted([5,1,2,[3,2,1,[1]]]) == sorted([1,[3,2,1,[1]],2,5])",
           number=10000)/10000
4.928951884845034e-06

虽然扩展到允许重复的情况并不容易。

【讨论】:

    【解决方案2】:

    当不存在重复条目时,通常的选择是:

    1. 如果元素是可散列的:set(a) == set(b)

    2. 如果元素是可订购的:sorted(a) == sorted(b)

    3. 如果你只有平等:len(a) == len(b) and all(x in b for x in a)

    如果您有重复并且它们的多重性很重要,那么选择是:

    1. 如果元素是可散列的:Counter(a) == Counter(b)

    2. 如果元素是可订购的:sorted(a) == sorted(b)

    3. 如果你只有平等:len(a) == len(b) and all(a.count(x) == b.count(x) for x in a)

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 2017-02-13
      • 1970-01-01
      • 2013-06-22
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多