字典列表中所有键的联合

Posted

技术标签:

【中文标题】字典列表中所有键的联合【英文标题】:Union of all keys from a list of dictionaries 【发布时间】:2013-06-03 17:31:03 【问题描述】:

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

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

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

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

谢谢!

【问题讨论】:

set([row.keys() for row in dictlist]) 不是您想要的。此外,它会导致TypeError 你说得对,我还没有真正尝试过。 【参考方案1】:

你可以试试:

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

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

【讨论】:

谢谢!这行得通,但我不知道为什么。您能帮我理解星号在这种情况下的作用吗?怎么只提取dictlist的key? 当然...* 将列表解压缩为set.union 的单独参数,它可以采用任意数量的可迭代参数...(因此上述调用实际上是 set().union( first_dict, second_dict,third_dict,fourth_dict...) 所以对于列表中的每个对象,它都会尝试迭代它(在 dict 的情况下是它的键,或者一个列表/元组它的项目,或者对于一个字符串它的字符......等等......) 啊,谢谢。这也有助于我理解星号的用途。【参考方案2】:

在 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它也可以在python2.7上工作。使用dict.viewkeys 而不是dict.keys

【讨论】:

不相信您需要方法调用... reduce(set.union, dicts, set()) 我相信应该可以工作... @JonClements -- 是的。我的想法是更多地展示python3.x中dict.keys的集合性质 嗯,好吧 - reduce(operator.or_, (d.keys() for d in dicts)) ? @JonClements -- 是的,我喜欢那个。我将使用它进行更新。【参考方案3】:

你可以这样做:

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

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

【讨论】:

chain 在这里做什么? 那行不通——它会尝试从每个字典中创建一个集合。你需要set(chain.from_iterable(dictlist)) 或其他东西。 我会选择@DSM - 绝对是chain.from_iterable - 它基本上是chain(*dictlist),但更优化(恕我直言,更明确一点)...... @JonClements,我在这里看不到chain.from_iterable 的优势。由于 dicts 和 dictlist 都已经存在,所以没有保存。 @gnibbler dictlist 可以是任何可迭代的。不仅仅是一个列表。【参考方案4】:

sets 就像字典一样,并且有一个 update() 方法,所以这将在您的循环中起作用:

keys.update(row.iterkeys())

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于字典列表中所有键的联合的主要内容,如果未能解决你的问题,请参考以下文章

python reduce找到集合的并集

从具有不同键的嵌套对象的值创建联合

Hibernate注解映射联合主键的三种主要方式

Hibernate注解映射联合主键的三种主要方式

打字稿中具有联合类型键的松散类型对象

Hibernate注解映射联合主键的三种主要方式(转载)