确保列表中的所有类型的字典具有相同的密钥(Make sure all dicts in a list

2019-09-17 01:51发布

我有一个像字典列表

[{'x': 42}, {'x': 23, 'y': 5}]

并希望确保所有类型的字典具有相同的钥匙,用值None如果该键不存在在原来的字典。 所以,上面的列表应该成为

[{'x': 42, 'y': None}, {'x': 23, 'y': 5}]

什么是最美丽,最Python的方式做到这一点? 目前的做法:

keys = reduce(lambda k, l: k.union(set(l)), [d.keys() for d in my_list], set())
new_list = [dict.fromkeys(keys, None) for i in xrange(len(my_list))]
for i, l in enumerate(my_list):
    new_list[i].update(l)

但是,尤其是前两行似乎那种笨拙。 想法?

Answer 1:

>>> from itertools import chain 
>>> l = [{'x': 42}, {'x': 23, 'y': 5}]
>>> all_keys = set(chain.from_iterable(l))   
>>> for d in l:
        d.update((k,None) for k in all_keys-d.viewkeys())


>>> l
[{'y': None, 'x': 42}, {'y': 5, 'x': 23}]


Answer 2:

最简单的方式做到这一点:

from itertools import chain

dicts = [{'x': 42}, {'x': 23, 'y': 5}]

keys = set(chain.from_iterable(dicts))
for item in dicts:
     item.update({key: None for key in keys if key not in item})

给我们:

[{'y': None, 'x': 42}, {'y': 5, 'x': 23}]

我们做的所有词典中所有的键,然后我们遍历一组dict s的任何值更新他们没有。

到使用替代itertools.chain.from_iterable()将是这样做reduce(or_, [dict.keys() for dict in dicts])使用functools.reduce()在3.x中,所述reduce()内置在2.X)和operator.or_ ,虽然我觉得这是不太可读。

如果你想创建一个新的列表,而不是更新旧的,只是为了与循环更换:

newdicts = [{key: item.get(key, None) for key in keys} for item in dicts]


Answer 3:

这将创建词典的新名单,他们都完全键:

>>> import itertools as it
>>> l = [{'x': 42}, {'x': 23, 'y': 5}]
>>> all_keys = set(it.chain.from_iterable(l))
>>> [dict((k, a.get(k, None)) for k in all_keys) for a in l]
[{'x': 42, 'y': None}, {'x': 23, 'y': 5}]


文章来源: Make sure all dicts in a list have the same keys