Python 字典列表中所有键的并集

Python 字典列表中所有键的并集,python,list,dictionary,Python,List,Dictionary,假设我有一个字典列表。它们在每一行中大多具有相同的键,但有一些不匹配,并且具有额外的键/值对。有没有一种快速的方法来获取所有行中的所有键集 现在我正在使用这个循环: def get_all_keys(dictlist): keys = set() for row in dictlist: keys = keys.union(row.keys()) 在一个数十万行的列表中执行此操作似乎效率极低,但我不知道如何做得更好 谢谢 集合类似于字典,有一个update()方

假设我有一个字典列表。它们在每一行中大多具有相同的键,但有一些不匹配,并且具有额外的键/值对。有没有一种快速的方法来获取所有行中的所有键集

现在我正在使用这个循环:

def get_all_keys(dictlist):
    keys = set()
    for row in dictlist:
        keys = keys.union(row.keys())
在一个数十万行的列表中执行此操作似乎效率极低,但我不知道如何做得更好


谢谢

集合
类似于字典,有一个
update()
方法,因此这将在您的循环中起作用:

keys.update(row.iterkeys())
你可以做:

from itertools import chain
return set(chain.from_iterable(dictlist))

正如@Jon Clements所指出的,这只能将所需的数据保留在内存中,而不是对
联合
使用
*
操作符。如果您担心性能,则应退出
dict.keys()
方法,因为它会在内存中创建列表。你可以用
set.update()
代替union,但我不知道它是否比
set.union()快,你可以试试:

def all_keys(dictlist):
    return set().union(*dictlist)

避免导入,并充分利用
set
的底层实现。也适用于任何可移植的对象。

在python3.x1上运行的一个有趣的对象依赖于
reduce
dict.keys()
现在返回一个类似集合的对象:

>>> from functools import reduce
>>> dicts = [{1:2},{3:4},{5:6}]
>>> reduce(lambda x,y:x | y.keys(),dicts,{})
{1, 3, 5}
不管它值多少钱

>>> reduce(lambda x,y:x | y.keys(),dicts,set())
{1, 3, 5}
也可以,或者,如果您想避免出现
lambda
(和初始值设定项),您甚至可以执行以下操作:

>>> reduce(operator.or_, (d.keys() for d in dicts))
非常整洁

当你只有两个元素时,这真的是最耀眼的。然后,你可以做
a.keys()| b.keys()
,而不是像set(a)| set(b)
这样的事情,这对我来说似乎更好一些



1它也可以用于Python 2.7。使用
dict.viewkeys
而不是
dict.keys

在这里
chain
做什么?那不管用——它会尝试从每个字典中创建一个集合。你需要
set(chain.from_iterable(dictlist))
或者别的什么。我在这里用@DSM-肯定是
chain。from_iterable
-它基本上是
chain(*dictlist)
,但是更优化了(而且更明确了一点)。@JonClements,我看不到
chain的优点。from iterable
。由于dicts和dictlist都已经存在,因此没有保存。@gnibbler dictlist可能是任何可编辑的。不仅仅是一个列表。不相信你需要方法调用
reduce(set.union,dicts,set())
我相信应该可以用…@JonClements——没错。我在这里的想法更多的是为了演示python3.xum中
dict.keys
的集合性质,好吧-
reduce(operator.or.[d.keys()表示dicts中的d))
?@JonClements——是的,我喜欢这个。我将使用它进行更新。
set([row.keys(),用于dictlist中的row])
不是您想要的。此外,它会导致一个
类型错误
。你是对的,我实际上还没有试过这个。谢谢!这是可行的,但我不知道为什么。你能帮我理解星号在这种情况下的作用吗?为什么它只从
目录列表中提取键呢。。。
*
将列表解压为单独的参数,这些参数可以接受任意数量的iterable参数。。。(因此上面的调用被有效地设置为().union(first_dict,second_dict,third_dict,fourth_dict…)因此对于列表中的每个对象,它都会尝试对其进行迭代(在
dict
的情况下,它是它的键,或者列表/元组是它的项,或者字符串是它的字符……等等)啊,谢谢。这也帮助我理解星号的用途。