我想获得具有以下结构的两个列表的差异:
first_dict = [{"a": "abcd","b":"defg", "c":["fng","xvg"]}, {"a": "stg","b":"klsm", "c":["xzy"]}]
second_dict = [{"a": "abcd","b":"defg", "c":["fng","xvg"]}]
我尝试按如下方式卡住集合:
i_set = { frozenset(row.items()) for row in first_dict }
a_set = { frozenset(row.items()) for row in second_dict }
result = [dict(i) for i in i_set - a_set]
预期结果:
v = {"a": "stg","b":"klsm", "c":["xzy"]}
因为 "c":[]
是一个列表,我收到以下错误:
TypeError: unhashable type: 'list'
最佳答案
由于您使用了 set
和 frozenset
我假设您关心效率并且不想要 O(n**2)
算法.
在这种情况下,您不仅需要将字典转换为卡住集,还需要将列表转换为可哈希类。您可以使用元组。
假设您的输入:
first_dict = [{"a": "abcd","b":"defg", "c":["fng","xvg"]}, {"a": "stg","b":"klsm", "c":["xzy"]}]
second_dict = [{"a": "abcd","b":"defg", "c":["fng","xvg"]}]
您可以使用:
def convert(dictionary):
return frozenset((key, tuple(value) if isinstance(value, list) else value) for key, value in dictionary.items())
def convert_back(frozset):
return dict((key, list(value) if isinstance(value, tuple) else value) for key, value in frozset)
i_set = { convert(row) for row in first_dict }
a_set = { convert(row) for row in second_dict }
result = [convert_back(i) for i in i_set - a_set]
那么结果将是:
[{'a': 'stg', 'c': ['xzy'], 'b': 'klsm'}]
但是,这不会区分原始元组中的元组和原始元组中列出的元组。
<小时/>您可以通过将字典包装在您自己的可哈希类中来解决这个问题(如果您确定字典及其内容在操作过程中不会发生变化)。这样做的优点是您不需要事后将它们转换回来,您可以简单地“解开”该值。
class HashableDictionaryWithListValues:
def __init__(self, dictionary):
converted = frozenset((key, tuple(value) if isinstance(value, list) else value) for key, value in dictionary.items())
self._hash = hash(converted)
self._converted = converted
self.dictionary = dictionary
def __hash__(self):
return self._hash
def __eq__(self, other):
return self._converted == other._converted
i_set = { HashableDictionaryWithListValues(row) for row in first_dict }
a_set = { HashableDictionaryWithListValues(row) for row in second_dict }
result = [i.dictionary for i in i_set - a_set]
结果将是:
[{'a': 'stg', 'b': 'klsm', 'c': ['xzy']}]
<小时/>
尽管您也可以避免整个转换/包装并执行 O(n**2)
方法:
def difference(first, second):
for item in first:
if item not in second:
yield item
list(difference(first_dict, second_dict))
这也给出了预期的结果:
[{'a': 'stg', 'b': 'klsm', 'c': ['xzy']}]
关于python - 比较Python中的字典列表和嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56414409/