在Python中为字典添加缺失的键
我有一个字典的列表:
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}]