从词典列表中联合所有键

时间:2013-06-03 17:31:03

标签: python list dictionary

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

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

def get_all_keys(dictlist):
    keys = set()
    for row in dictlist:
        keys = keys.union(row.keys())

在包含数十万行的列表中执行此操作似乎非常低效,但我不确定如何更好地执行此操作

谢谢!

5 个答案:

答案 0 :(得分:10)

你可以尝试:

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

避免导入,并将充分利用set的底层实现。也可以使用任何可迭代的东西。

答案 1 :(得分:4)

一个适用于python3.x 1 的有趣的一个依赖于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))

非常整洁。

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


1 也可以在python2.7上工作。使用dict.viewkeys代替dict.keys

答案 2 :(得分:3)

你可以这样做:

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

正如@Jon Clements所指出的,与*chain使用union运算符相比,这只能保留内存中所需的数据。

答案 3 :(得分:1)

sets就像字典一样,并且有一个update()方法,所以这可以在你的循环中运行:

keys.update(row.iterkeys())

答案 4 :(得分:0)

如果您担心性能,则应退出dict.keys()方法,因为它会在内存中创建一个列表。您可以使用set.update()代替联合,但我不知道它是否比set.union()更快。