字典键的交集是啥
Posted
技术标签:
【中文标题】字典键的交集是啥【英文标题】:What is the intersection of the keys of dictionaries字典键的交集是什么 【发布时间】:2019-06-25 15:53:13 【问题描述】:我正在尝试使用 map、filter、reduce 编写一个单行函数,它采用字典列表 (Ld) 并返回包含在所有字典中的键的集合(键的交集) .
下面的函数试图做到这一点。如果键在特定字典中,则映射部分返回 True/False 集合。如果所有这些元素都为真,reduce 将返回 True。最后,filter部分过滤掉所有不满足这些条件的key。
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 函数定义中的任何想法?以及如何解决这个问题的任何想法?
【问题讨论】:
我无法重现您的错误。它似乎工作得很好(一旦我提供了合适的all_keys
定义和list
-ify 生成的filter
对象):Try it online!。你能提供追溯或其他什么吗?
【参考方案1】:
filter
、reduce
、map
和 lambda
...天哪!记住,这是 Python,所以不要让它变得比它需要的更难。只需使用一个好的 ol' for 循环:
>>> 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
【讨论】:
【参考方案2】:您可以考虑使用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]
【讨论】:
key 视图已经是 set-like 的,所以将它们显式转换为 set 有点浪费。【参考方案3】:我无法重现您的错误。如果我运行您提供的代码(用(k for d in Ld for k in d)
替换all_keys(Ld)
,并将调用包装在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,因此您可以将许多相交的东西作为一个操作传递给它。
【讨论】:
以上是关于字典键的交集是啥的主要内容,如果未能解决你的问题,请参考以下文章