我正在尝试使用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函数定义的任何想法?以及有关如何解决此问题的任何想法?
答案 0 :(得分:2)
filter
,reduce
,map
和lambda
...哦,天哪!请记住,这是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]
虽然是多余的,但它按照重叠键的显示顺序准确地描述了它们。
也就是说,如果您不需要 用.keys()
/ map
/ filter
/ reduce
来编写它,只要不需要键的确切顺序和上面显示的输出冗余,很多方法都可以实现:
def intersection_of_keys(Ld):
return set(Ld[0]).intersection(*Ld[1:])
就是这样; set.intersection
takes varargs,因此您可以通过一次操作传递许多要相交的东西。