我要返回两个字典的True,它们在成员上是相等的(成员是每个词典的内容,不考虑列表的顺序),否则返回False。在python中执行此操作的好方法是什么?
例如,如果a = [dict1,dict2]和b = [dict2,dict1],则a等于b。 (dict1和dict2的键和值必须匹配。)
这是我的方式:
def _compare(self, a,b):
if len(a) != len(b):
return False
for d in a:
if d in b:
continue
else:
return False
return True
答案 0 :(得分:1)
这是为了很好地比较成员:
a.keys() == b.keys()
keys()
返回有关字典成员的视图。
要使用2个字典列表来完成此工作,只需将其包装成一个理解即可:
[a.keys() == b.keys() for a, b in zip(list1, list2)]
它将返回True和False的列表。
如果您想知道它们都是相等的,则只需用all()
将其包装起来,那么最终结果是:
all([a.keys() == b.keys() for a, b in zip(list1, list2)])
a = {}
b = {}
for i in range(100_0000):
a[i] = i
b[i] = i
In [10]: %timeit a==b # wrong, but just for comparison
11.6 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [11]: %timeit a.keys()==b.keys()
16.9 ms ± 209 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [17]: %timeit _compare(a, b)
30.6 ms ± 633 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [18]: %timeit set(a.keys()) == set(b.keys())
71 ms ± 1.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
答案 1 :(得分:0)
(问题有点模棱两可。据我所知,a
和b
都是包含字典的列表,您想检查两个列表是否以相同的顺序包含相同的字典)
您可以只使用内置的all
,尽管对于长列表(具有O(n²))来说这会很慢:
>>> lst1 = [{1:2, 3:4}, {5:6, 7:8}]
>>> lst2 = [{7:8, 5:6}, {3:4, 1:2}]
>>> len(lst1) == len(lst2) and all(x in lst2 for x in lst1)
True
更好地将list
的{{1}}转换为dict
的{{1}}并保存dict项,且O(n):
set
附录:这要求字典中的值是可哈希的。此外,它假定在同一列表中没有重复的dict(但是在这种情况下,您的代码也将不起作用,因此我认为这种假设是有效的)。如果有重复项,请使用another answer中所示的frozenset
。
答案 2 :(得分:0)
一种方法是比较一组值:
da = { 1:'a', 2:'b', 3:'c'}
db = { 3:'a', 1:'b', 2:'c'}
set(db.values()) == set(da.values())
答案 3 :(得分:0)
您可以先将列表中的dict转换为项的元组,然后使用collections.Counter
比较两个列表,而不考虑顺序:
from collections import Counter
def compare(a, b):
return Counter(tuple(d.items()) for d in a) == Counter(tuple(d.items()) for d in b)
,以便比较以下两个成员相等的字典列表:
compare(
[{1: 2, 2: 3}, {3: 4, 5: 6}, {3: 4, 5: 6}],
[{3: 4, 5: 6}, {1: 2, 2: 3}, {3: 4, 5: 6}]
)
返回True
。