19

我有 5 个字典,我想要它们的键的联合。

alldict =  [dict1, dict2, dict3, dict4, dict5]

我试过

allkey = reduce(lambda x, y: set(x.keys()).union(y.keys()), alldict)

但它给了我一个错误

AttributeError: 'set' object has no attribute 'keys'

我做错了吗?我使用普通的forloop,但我想知道为什么上面的代码不起作用。

4

5 回答 5

66

我认为@chuck 已经回答了为什么它不起作用的问题,但是更简单的方法是记住该union方法可以采用多个参数:

allkey = set().union(*alldict)

在没有任何循环或 lambda 的情况下做你想做的事。

于 2011-03-09T08:42:12.197 回答
10

您的解决方案适用于列表中的前两个元素,但随后dict1dict2缩减为一个集合,该集合作为x. 所以现在x没有办法keys()了。

解决方案是通过使用空集(恰好是并集的中性元素)初始化归约,使 x 从一开始就成为一个集合。

尝试使用初始化程序:

allkey = reduce(lambda x, y: x.union(y.keys()), alldict, set())

没有任何 lambda 的替代方法是:

allkey = reduce(set.union, map(set, map(dict.keys, alldict)))
于 2011-03-09T06:49:47.017 回答
5

非功能性神经元的简单策略(双关语):

allkey = []

for dictio in alldict:
    for key in dictio:
        allkey.append(key)

allkey = set(allkey)

我们可以使用集合推导将此代码转换为更排序的形式:

allkey = {key for dictio in alldict for key in dictio}

与传统的 for 循环相比,这个单行代码仍然非常具有可读性。将嵌套循环转换为列表或集合理解的关键是将内部循环(在嵌套循环中变化更快的循环)编写为最后一个索引(即 for key in dictio)。

于 2011-03-09T07:36:21.633 回答
1

只是另一种方式,因为干草:

a={}; [ a.update(b) for b in alldict ] and a.keys()

或者更神秘的

reduce(lambda a, b: a.update(b) or a, alldict, {}).keys()

(我很沮丧,没有内置函数相当于

def f(a,b):
   r = {}
   r.update(a)
   r.update(b)
   return r

有没有?)

于 2011-03-09T07:55:51.827 回答
1
set().union(dict1.keys(),dict2.keys()...)

我试过这个列表,但它没有用,所以只是把它放在这里给任何人。

于 2013-07-16T08:00:42.473 回答