代码之家  ›  专栏  ›  技术社区  ›  user1008636

比较两个词典列表

  •  3
  • user1008636  · 技术社区  · 7 年前

    我想返回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
    
    4 回复  |  直到 7 年前
        1
  •  1
  •   tobias_k    7 年前

    (这个问题有点模棱两可。据我所知, 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 属于 dict set 属于 frozenset 握着听写项目,有O(n):

    >>> set_of_tuples = lambda l: set(frozenset(d.items()) for d in l)
    >>> set_of_tuples(lst1)
    set([frozenset([(1, 2), (3, 4)]), frozenset([(5, 6), (7, 8)])])
    >>> set_of_tuples(lst1) == set_of_tuples(lst2)
    True
    

    Counter 如所示 another answer

        2
  •  1
  •   PascalVKooten    7 年前

    这是为了更好地比较成员:

    a.keys() == b.keys()
    

    keys() 返回字典成员的视图。

    要使用两个听写列表,只需将其包装在理解中:

    [a.keys() == b.keys() for a, b in zip(list1, list2)]
    

    如果你想知道他们都是平等的,那就用 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)
    
        3
  •  0
  •   gregory    7 年前

    一种方法是比较一组值:

    da = { 1:'a', 2:'b', 3:'c'}
    db = { 3:'a', 1:'b', 2:'c'}
    
    set(db.values()) == set(da.values())
    
        4
  •  0
  •   blhsing    7 年前

    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)
    

    因此,以下两个成员级dict列表的比较相等:

    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