Python中字典内的比较列表

Python中字典内的比较列表,python,python-2.7,Python,Python 2.7,我有两本字典,价值部分有一个列表。像这样的 dict1 = {red:[1,2,3], blue:[7,6,9], green:[3,9,3,1]} dict2 = {red:[2,1,3], blue:[9,7,6], green:[3,9,1,3]} 在这种情况下,比较必须给出一个True,因为在这两个字典中,给定键的列表中包含相同的值。我提出了一个解决方案,其中我使用键访问列表值。然后检查列表的长度是否相同,以及一个列表中的每个值是否存在于另一个列表中。 我认为在python中还有其他方

我有两本字典,价值部分有一个列表。像这样的

dict1 = {red:[1,2,3], blue:[7,6,9], green:[3,9,3,1]}
dict2 = {red:[2,1,3], blue:[9,7,6], green:[3,9,1,3]}
在这种情况下,比较必须给出一个True,因为在这两个字典中,给定键的列表中包含相同的值。我提出了一个解决方案,其中我使用键访问列表值。然后检查列表的长度是否相同,以及一个列表中的每个值是否存在于另一个列表中。
我认为在python中还有其他方法可以做到这一点。最好的“pythonic”方法是什么?

如果您希望比较两个忽略值顺序的列表,可以将每个列表转换为set

dict1 = {"red": [1, 2, 3], "blue": [7, 6, 9], "green": [3, 9, 3, 1]}
dict2 = {"red": [2, 1, 3], "blue": [9, 7, 6], "green": [3, 9, 1, 3]}


def compare_dicts(a, b):
    if set(a.keys()) != set(b.keys()):
        # If the keys do not match,
        # the dicts can't be equal.
        return False

    for key, value in a.items():
        if key not in b:
            # If a key does not exist in `b`,
            # but exists in `a`, the dicts
            # can't be equal.
            return False

        if sorted(value) != sorted(b[key]):
            # If the sorted lists of values aren't
            # equal, the dicts can't be equal.
            return False

            # Every other case failed to exit, so the dicts
            # must be equal.
    return True


print(compare_dicts(dict1, dict2))
set(list1) == set(list2)

您可以使用
set
比较包含相同元素但顺序不同的两个列表

>>> dict1 = {'red':[1,2,3], 'blue':[7,6,9], 'green':[3,9,3,1]}
>>> dict2 = {'red':[2,1,3], 'blue':[9,7,6], 'green':[3,9,1,3]}
>>> all(set(v) == set(dict2.get(k)) for k,v in dict1.items())
True
如果可以重复dict值,请使用排序后的
进行比较

>>> all(sorted(v) == sorted(dict2.get(k)) for k,v in dict1.items())
True

@aaroh然后只需为字典键添加一层额外的检查。@Chris_Rands:
计数器(a)==计数器(b)
允许您执行相同的测试O(N)时间。除非值不可散列,否则不要使用排序。Python 2解决方案:
从集合导入计数器
,然后
a.viewkeys()==b.viewkeys()和all(计数器(v)==Counter(b[k]),用于k,v在a.iteritems()中)
。这在O(N)时间内解决了这个问题,其中
N
是所有列表中的条目总数,只要发现键不匹配或任何值列表不相等,就会提前退出。@Chris_Rands:这是Python 2,因此
map()
不需要
list()
。你假设这些键将按相同的顺序列出,而它们通常不会。@Chris_Rands:你需要先测试这些键是否相等
a.viewkeys()==b.viewkeys()
在两个键集合之间高效地进行设置比较。然后,您需要确保比较每个配对键的计数器。如果不匹配,您希望提前退出,并避免在您已经知道答案时创建更多的
Counter()
对象,因此使用
all()
。这假设每个列表中的值都是唯一的。对于具有重复值的列表,这将忽略重复计数!排序意味着我正在增加复杂性,有没有更好的方法?不要使用排序,使用
collection.Counter
objects:
Counter(value)!=计数器(b[键])
。不要使用
set()
对象,Python是集合,可以直接比较:
a.viewkeys()!=b、 viewkeys()
。如果您的
键不在b:
测试中是多余的,则您已经确定两个字典中的键匹配。在Python2中不要使用
a.items()
,使用
a.iteritems()
a.viewitems()
返回a.viewkeys()==b.viewkeys()和all(计数器(v)==Counter(b[k]),对于k,在a.iteritems()中使用
就足够了。这假设每个列表中的值都是唯一的。对于具有重复值的列表,这将忽略重复计数!