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()中使用就足够了。这假设每个列表中的值都是唯一的。对于具有重复值的列表,这将忽略重复计数!