dict_values交集和可哈希类型

问题描述 投票:-1回答:3

我想检查两个字典的交集。如果执行此操作,则完全可以达到我的期望:

dict1 = {'x':1, 'y':2, 'z':3}
dict2 = {'x':1, 'y':2, 'z':4}

set(dict1.items()).intersection(dict2.items())
>> {('x', 1), ('y', 2)}

但是,如果字典中[的项目不可散列,则会出现错误。

dict1 = {'x':{1,2}, 'y':{2,3}, 'z':3} dict2 = {'x':{1,3}, 'y':{2,4}, 'z':4} TypeError Traceback (most recent call last) <ipython-input-56-33fdb931ef54> in <module> ----> 1 set(dict1.items()).intersection(dict2.items()) TypeError: unhashable type: 'set'
当然,对于元组和列表,我也会遇到相同的错误,因为它们也不是可哈希的。 

是否可以使用变通方法或现有类来检查不可哈希的字典值的交集?

python dictionary intersection hashset
3个回答
0
投票
也许尝试:

#!/usr/local/cpython-3.8/bin/python3 def intersection1(dict1, dict2): intersection = set(dict1.items()).intersection(dict2.items()) return intersection def intersection2(dict1, dict2): result = {} for key1 in dict1: if key1 in dict2 and dict1[key1] == dict2[key1]: result[key1] = dict1[key1] return result def main(): dict1 = {'x': 1, 'y': 2, 'z': 3} dict2 = {'x': 1, 'y': 2, 'z': 4} print(intersection2(dict1, dict2)) print(intersection1(dict1, dict2)) # >> {('x', 1), ('y', 2)} dict3 = {'x': [1, 2], 'y': [2, 3], 'z': [3, 4]} dict4 = {'x': [1, 2], 'y': [2, 3], 'z': [4, 5]} print(intersection2(dict3, dict4)) print(intersection1(dict3, dict4)) main()

您当然不能将不可散列的类型放入集合中,所以我用交集2()做了下一件最好的事情

0
投票
您可以在执行集合相交之前序列化dict值,并反序列化结果集中的值。以下示例使用pickle进行序列化:

import pickle {k: pickle.loads(v) for k, v in set.intersection( *({(k, pickle.dumps(v)) for k, v in i} for i in map(dict.items, (dict1, dict2))))}

因此,给定:

dict1 = {'x': {1, 2}, 'y': {2, 3}, 'z': 3} dict2 = {'x': {2, 1}, 'y': {2, 4}, 'z': 4}

表达式将返回:

{'x': {1, 2}}


0
投票
您可以创建一个“ makeHashable”函数以应用于比较目的的字典项目,并使用它来构建一个集合,然后可以检查列表推导:

dict1 = {'x':{1,2}, 'y':{2,3}, 'z':3} dict2 = {'x':{1,3}, 'y':{3,2}, 'z':4} def makeHashable(x): if isinstance(x,(list,tuple)): return tuple(map(makeHashable,x)) if isinstance(x,set): return makeHashable(sorted(x)) if isinstance(x,dict): return tuple(map(makeHashable,x.items())) return x dict1Set = set(map(makeHashable,dict1.items())) intersect = [ kv for kv in dict2.items() if makeHashable(kv) in dict1Set]

输出:

print(intersect) # [('y', {2, 3})]

© www.soinside.com 2019 - 2024. All rights reserved.