不可用对象的无序集合?

时间:2011-11-30 20:46:33

标签: python collections

我有一个字典,其中一些值不可清除。我需要一些方法来比较这两个无序组,以确保它们包含相同的元素。我不能使用列表,因为列表相等性会考虑订单,但设置不起作用,因为dicts不可清除。我查看了python文档,唯一看起来有用的东西是dict的视图,在某些情况下可以清除,但在这种情况下,这也没有帮助,因为其中一个值是一个包含列表本身的对象,这意味着dict的视图也不会是可以播放的。

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

2 个答案:

答案 0 :(得分:11)

如果不存在重复的条目,通常的选择是:

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

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

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

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

    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)

答案 1 :(得分:2)

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

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

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