在Python中添加字典中缺少的键

时间:2015-11-25 07:29:56

标签: python dictionary key

我有一个词典列表:

L = [{0:1,1:7,2:3,4:8},{0:3,2:6},{1:2,4:6}....{0:2,3:2}]. 

正如您所看到的,词典的长度不同。我需要的是添加缺少的键:每个字典的值使它们具有相同的长度:

L1 = [{0:1,1:7,2:3,4:8},{0:3,1:0,2:6,3:0,4:0},{0:0, 1:2,3:0,4:6}....{0:2,1:0,2:0,3:2,4:0}], 

意味着为缺失值添加零。最大长度不是事先给出的,因此可以只通过列表迭代它。

我尝试使用默认设置,例如L1 = defaultdict(L),但似乎我不能正确理解它是如何工作的。

6 个答案:

答案 0 :(得分:4)

你必须做两次通过:1来获得所有键的联合,另一次来添加缺失的键:

max_key = max(max(d) for d in L)
empty = dict.fromkeys(range(max_key + 1), 0)
L1 = [dict(empty, **d) for d in L]

这使用了空白'字典作为快速生成所有键的基础;此词典的新副本加上原始词典会生成您想要的输出。

请注意,这假设您的密钥始终是连续的。如果不是,则可以生成所有现有密钥的并集:

empty = dict.fromkeys(set().union(*L), 0)
L1 = [dict(empty, **d) for d in L]

演示:

>>> L = [{0: 1, 1: 7, 2: 3, 4: 8}, {0: 3, 2: 6}, {1: 2, 4: 6}, {0: 2, 3: 2}]
>>> max_key = max(max(d) for d in L)
>>> empty = dict.fromkeys(range(max_key + 1), 0)
>>> [dict(empty, **d) for d in L]
[{0: 1, 1: 7, 2: 3, 3: 0, 4: 8}, {0: 3, 1: 0, 2: 6, 3: 0, 4: 0}, {0: 0, 1: 2, 2: 0, 3: 0, 4: 6}, {0: 2, 1: 0, 2: 0, 3: 2, 4: 0}]

或设定方法:

>>> empty = dict.fromkeys(set().union(*L), 0)
>>> [dict(empty, **d) for d in L]
[{0: 1, 1: 7, 2: 3, 3: 0, 4: 8}, {0: 3, 1: 0, 2: 6, 3: 0, 4: 0}, {0: 0, 1: 2, 2: 0, 3: 0, 4: 6}, {0: 2, 1: 0, 2: 0, 3: 2, 4: 0}]

将两个词典合并为dict(d1, **d2)的新词典的上述方法始终适用于Python 2.在Python 3中,已经设置了可以使用此技巧的哪种键的附加约束;第二个字典只允许字符串键。对于此示例,如果您有 numeric 键,则可以使用其字典视图的并集:

dict(d.items() | empty.items())  # Python 3 dictionary merge

答案 1 :(得分:2)

这只是 a 解决方案,但我认为它简单明了。请注意,它会修改字典到位,因此如果您希望将它们复制,请告诉我,我会相应地进行修改。

keys_seen = []
for D in L:  #loop through the list
    for key in D.keys():  #loop through each dictionary's keys
        if key not in keys_seen:  #if we haven't seen this key before, then...
            keys_seen.append(key)  #add it to the list of keys seen

for D1 in L:  #loop through the list again
    for key in keys_seen:  #loop through the list of keys that we've seen
        if key not in D1:  #if the dictionary is missing that key, then...
            D1[key] = 0  #add it and set it to 0

答案 2 :(得分:2)

也许不是最优雅的解决方案,但应该有效:

L = [{0:1,1:7,2:3,4:8},{0:3,2:6},{1:2,4:6},{0:2,3:2}]

alldicts = {}
for d in L:
    alldicts.update(d)

allkeys = alldicts.keys()

for d in L:
    for key in allkeys:
        if key not in d:
            d[key] = 0

print(L)

答案 3 :(得分:2)

有点谨慎:改变L

>>> allkeys = frozenset().union(*L)
>>> for i in L:
...    for j in allkeys:
...        if j not in i:
...            i[j]=0

>>> L
[{0: 1, 1: 7, 2: 3, 3: 0, 4: 8}, {0: 3, 1: 0, 2: 6, 3: 0, 4: 0}, {0: 0, 1: 2, 2:
 0, 3: 0, 4: 6}, {0: 2, 1: 0, 2: 0, 3: 2, 4: 0}]

答案 4 :(得分:0)

除非None是字典密钥的有效值,否则此处为您提供了一个很好的解决方案

L = [{0: 1, 1: 7, 2: 3, 4: 8}, {0: 3, 2: 6}, {1: 2, 4: 6}, {0: 2, 3: 2}]
for i0, d0 in enumerate(L[:-1]):
    for d1 in L[i0:]:
        _ = [d0.__setitem__(k,d1[k]) for k in d1 if d0.get(k,None) is None]
        _ = [d1.__setitem__(k,d0[k]) for k in d0 if d1.get(k,None) is None]

print(L)
>>> [{0: 1, 1: 7, 2: 3, 3: 2, 4: 8}, {0: 3, 1: 2, 2: 6, 3: 2, 4: 6}, {0: 2, 1: 2, 2: 3, 3: 2, 4: 6}, {0: 2, 1: 7, 2: 3, 3: 2, 4: 8}]

答案 5 :(得分:0)

这又快又苗条:

missing_keys = set(dict1.keys()) - set(dict2.keys())
for k in missing_keys:
    dict1[k] = dict2[k]