在Python中为字典添加缺失的键

5 投票
6 回答
11387 浏览
提问于 2025-05-11 01:55

我有一个字典的列表:

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}], 

也就是说,要为缺失的值添加零。最大长度事先并不知道,所以只能通过遍历这个列表来找到。

我尝试使用defaultdict来实现,比如 L1 = defaultdict(L),但我好像不太明白它是怎么工作的。

相关文章:

  • 暂无相关问题
暂无标签

6 个回答

1

这个方法简单又高效:

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

这只是一个解决方案,但我觉得它简单明了。请注意,它是直接在原来的字典上进行修改的,所以如果你想要的是字典的副本,请告诉我,我会相应地进行调整。

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
3

这可能不是最完美的解决方案,但应该可以正常工作:

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)
8

你需要进行两次操作:第一次是获取所有键的并集,第二次是添加缺失的键:

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中,对可以使用这种技巧的键类型有了额外的限制;第二个字典只能使用字符串键。对于这个例子,如果你的键是数字,你可以改用字典解包的方法:

{**empty, **d}  # Python 3 dictionary unpacking

这样在Python 3.5及更新版本中都能正常工作。

3

稍微注意一下:更改 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}]

撰写回答