我试图找到一种方法来排序和比较Python 3.6中的两个字典列表。我最终只希望list_dict_a
和list_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'}]
数据是相同的,但它有不同的顺序(我对初始订单没有任何控制权)。
当我尝试比较它们时,我在做这样的事情时会得到一个假值:
print("does this match anything",list_dict_a == list_dict_b)
这甚至可以吗?
答案 0 :(得分: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
每个列表中的dicts顺序无关紧要。
需要传递key
函数,因为dicts是不可订购的,因此我们需要告诉排序函数在比较它们时对每对dict对象使用什么键。每个字典的键只是其(键,值)对的排序列表。
key函数为每个dict计算一个键,如下所示:
>>> dict_a0 = list_dict_a[0]
>>> key_func(dict_a0)
[('expiration_date', ''), ('identifier_country', ''), ('identifier_number', 'Male'), ('identifier_type', 'Gender'), ('issue_date', '')]
<强>脚注强>
为了使这个(键,值)对的列表与其他词组相比较,列表,None
值必须转换为空字符串。这允许None值与其他非None值相比。
上述解决方案中的基本假设是,您的案例中的所有字典值都是字符串或None
,并且&#34;空&#34;值始终表示为None
(而不是例如空字符串)。如果不是这种情况,则必须相应地调整key_func()
,以确保结果列表始终与数据中预期的任何字典值相互比较。
此外,对于大型dicts,这个关键功能可能并不理想,因为密钥对的比较会太慢。因此,最好为每个字典计算一个唯一的哈希值(但对于比较相等的字母,则使用相同的哈希值)。
答案 1 :(得分:0)
您还可以检查list_dict_a中的每个字典是否在list_dict_b
中all([dict_a in list_dict_b for dict_a in list_dict_a])
Out[218]: True
答案 2 :(得分:0)
你可以试试这个:
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'}]
new_list = sorted(list_dict_a, key=lambda x:x['identifier_country'] is not None, reverse=True)
print(new_list == list_dict_b)
输出:
True
如果您最初不知道密钥,可以试试这个:
new_list = sorted(list_dict_a, key=lambda x:x.get('identifier_country', None) is not None, reverse=True)