字典列表中所有键的联合
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 所指出的,这与将*
运算符用于chain
或union
相比,只能将所需的数据保留在内存中。
【讨论】:
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()
快。
【讨论】:
以上是关于字典列表中所有键的联合的主要内容,如果未能解决你的问题,请参考以下文章