字典键的交集是什么

时间:2019-02-01 05:13:29

标签: python dictionary lambda filter reduce

我正在尝试使用map,filter,reduce编写一个线性函数,该函数采用的是字典列表(Ld),并返回所有字典中包含的键的集合(键的交集)

下面的函数尝试执行此操作。如果键在特定字典中,则映射部分将返回True / False的集合。如果所有这些元素都为true,则reduce返回True。最后,过滤器部分过滤掉所有不满足这些条件的键。

def intersection_of_keys(Ld):
    return filter(lambda key: reduce(lambda x, y: x*y, map(lambda dic: key in dic, Ld)), all_keys(Ld))

#For example:  
d1 = {1:12, 3:4, 2:5}  
d2 = {1:6, 3:8, 0:9}  
d3 = {3:0, 1:11, 2:3}  
Ld = [d1, d2, d3]  
print(intersection_of_keys(Ld))  

代码应打印包含1和3的集合。但是 map 部分中的变量 key 是未定义的。为什么没有将 key 传递给地图的lambda函数定义的任何想法?以及有关如何解决此问题的任何想法?

3 个答案:

答案 0 :(得分:2)

filterreducemaplambda ...哦,天哪!请记住,这是Python,所以不要使其变得比需要的难。只是使用一个好的ol'循环:

>>> keys, *morekeys = [d.keys() for d in Ld]
>>> for k in morekeys: 
...     keys &= k 
...
>>> keys
{1, 3}

如果您坚持使用reduce,就像这样:

>>> from functools import reduce
>>> from operator import and_
>>> reduce(and_, [d.keys() for d in Ld])
{1, 3}

答案 1 :(得分:1)

您可以考虑使用一个带有set&的衬纸:

from functools import reduce

d1 = {1:12, 3:4, 2:5}  
d2 = {1:6, 3:8, 0:9}  
d3 = {3:0, 1:11, 2:3}  
Ld = [d1, d2, d3]

reduce(lambda x, y: x&y.keys(), Ld)
>>>{1, 3}

如果您不能使用set&,而必须坚持使用reduce

reduce(lambda x, y: [i for i in x if i in y], Ld)
>>>[1, 3]

最后,如果您甚至无法使用列表推导功能,而需要使用filter

list(reduce(lambda x, y: filter(lambda a: a in y, x) , Ld))
>>>[1, 3]

答案 2 :(得分:1)

我无法重现您的错误。如果我运行您提供的代码(将all_keys(Ld)替换为(k for d in Ld for k in d),并将调用包装在list中,以使filter用完),我得到:

[1, 3, 1, 3, 3, 1]

Try it online!

虽然是多余的,但它按照重叠键的显示顺序准确地描述了它们。

也就是说,如果您不需要 .keys() / map / filter / reduce来编写它,只要不需要键的确切顺序和上面显示的输出冗余,很多方法都可以实现:

def intersection_of_keys(Ld):
    return set(Ld[0]).intersection(*Ld[1:])

就是这样; set.intersection takes varargs,因此您可以通过一次操作传递许多要相交的东西。