排序和比较字典列表 Python

uns*_*age 6 python sorting dictionary list python-3.x

我试图找到一种方法来排序和比较 Python 3.6 中的两个字典列表。我最终只是想list_dict_alist_dict_b有比较==和评价True

下面是数据的样子:

list_dict_a = [
{'expiration_date': None, 'identifier_country': None, 'identifier_number': 'Male', 'identifier_type': 'Gender', 'issue_date': None},
{'expiration_date': None, 'identifier_country': 'VE', 'identifier_number': '1234567', 'identifier_type': 'Foo No.', 'issue_date': None}]

list_dict_b = [
{'identifier_country': 'VE', 'expiration_date': None, 'identifier_type': 'Foo No.', 'issue_date': None, 'identifier_number': '1234567'},
{'identifier_country': None, 'expiration_date': None, 'identifier_type': 'Gender', 'issue_date': None, 'identifier_number': 'Male'}]
Run Code Online (Sandbox Code Playgroud)

数据是相同的,但它的顺序不同(我对初始顺序没有任何控制权)。

当我尝试将它们进行比较时,在执行以下操作时会得到一个错误值: print("does this match anything",list_dict_a == list_dict_b)

这甚至可以做到吗?

pla*_*mut 2

您可以在比较之前对两个列表进行排序并比较排序结果:

>>> list_dict_a = [
        {'expiration_date': None, 'identifier_country': None, 'identifier_number': 'Male', 'identifier_type': 'Gender', 'issue_date': None},
        {'expiration_date': None, 'identifier_country': 'VE', 'identifier_number': '1234567', 'identifier_type': 'Foo No.', 'issue_date': None}]

>>> list_dict_b = [
        {'identifier_country': 'VE', 'expiration_date': None, 'identifier_type': 'Foo No.', 'issue_date': None, 'identifier_number': '1234567'},
        {'identifier_country': None, 'expiration_date': None, 'identifier_type': 'Gender', 'issue_date': None, 'identifier_number': 'Male'}]

>>> list_dict_a == list_dict_b
False
>>> def key_func(d):
        items = ((k, v if v is not None else '') for k, v in d.items())
        return sorted(items)
>>> sorted(list_dict_a, key=key_func) == sorted(list_dict_b, key=key_func)
True
Run Code Online (Sandbox Code Playgroud)

每个列表中的字典顺序将不再重要。

需要传递该key函数,因为字典是不可排序的,因此我们需要告诉排序函数在比较每对字典对象时使用什么键。每个字典的键只是其(键,值)对的排序列表。

key 函数计算每个字典的键,如下所示:

>>> dict_a0 = list_dict_a[0]
>>> key_func(dict_a0)
[('expiration_date', ''), ('identifier_country', ''), ('identifier_number', 'Male'), ('identifier_type', 'Gender'), ('issue_date', '')]
Run Code Online (Sandbox Code Playgroud)

脚注

为了使这个(键,值)对列表与其他字典的列表进行比较,None值必须转换为空字符串。这使得 None 值可以与其他非 None 值进行比较。

上述解决方案的基本假设是,您的情况下的所有字典值都是字符串或None,并且“空”值一致表示为None(而不是例如空字符串)。如果情况并非如此,key_func()则必须进行相应调整,以确保结果列表对于数据中预期的任何字典值始终可以相互比较。

此外,对于大型字典,此键功能可能并不理想,因为键对的比较太慢。因此,最好为每个字典计算唯一的哈希值(但对于比较相等的字典使用相同的哈希值)。