【发布时间】:2017-03-01 20:08:05
【问题描述】:
我想找到一种简单和/或快速的方法来查找所有 common 对(对:值)给定 Python 中的 N 个字典。 (3.X 最好)
问题
给定一组 3 个dicts(但它可以是任何dict,这只是示例)
n1 = {'a': 1, 'b': 2, 'c': 3}
n2 = {'a': 1, 'b': 4, 'c': 3, 'd': 4}
n3 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
n1、n2 和 n3 的公共(键:值)的结果
应该是:
({'a': 1, 'c': 3})
对于n2 和n3 应该是
({'a': 1, 'c': 3, 'd': 4})
我首先考虑使用 brute force 算法来检查每个字典的每一对(键:值)
这是一个使用递归算法的实现
解决方案 A
list_dict = [n1, n2, n3]
def finding_uniquness(ls):
def recursion(ls, result):
if not ls:
return result
result = {k: v for k, v in result.items() for k1, v1 in ls[0].items() if k == k1 and v == v1}
return recursion(ls[1:], result)
return recursion(ls[1:], ls[0])
finding_uniquness(list_dict)
# {'c': 3, 'a': 1}
但不易理解,复杂度高
(我不确定如何计算复杂度;但是由于我们比较了所有dict 上的所有元素,所以复杂度应该是O(N²)?)
然后,我想到了Sets。因为它可以自然地比较所有元素
解决方案 B
import functools
list_dict = [n1, n2, n3]
set_list = [set(n.items()) for n in list_dict]
functools.reduce(lambda x, y: x & y, set_list)
# {('a', 1), ('c', 3)}
不幸的是,它比以前的解决方案要好得多,当key 之一具有list 作为值时,它会引发错误:
>>> n = {'a': [], 'b': 2, 'c': 3}
>>> set(n.items())
TypeError: unhashable type: 'list'
我的问题是双重的:
- 还有比SOLUTION A更好的算法吗?
- 或者有没有办法通过解决方案B避免
TypeError?
当然,欢迎任何其他评论。
【问题讨论】:
-
您多次说“唯一”,但实际上您似乎在寻找 common 键:值对?换句话说,所有字典共享的那个。
-
您的字典中有哪些类型?平面列表?列表列表?因为您可以事先转换为
tuple,这样哈希问题就消失了。 -
@roganjosh 例如,这将使
6和"6"相等。repr可能更安全 -
专业提示:在 python3 中,
.items()、.values()和.keys()已经返回 set-like 对象,因此无需执行set(d.items())!跨度> -
顺便说一句,好问题。展示研究,并产生一些不错的答案(这是一个标志:))
标签: python algorithm python-3.x dictionary