我有两个词典项目和 u_items
items = {"A": 1, "B": 2, "C": 3}
u_items = {"D": 4, "B": 4, "E": 8, "C": 4}
我想用u_items更新项目字典,所以我做到了
items.update((k + '_1' if k in items else k, v) for k, v in u_items.items())
这样我就可以区分两个字典的键
输出:
items = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4}
但是当我用另一个字典更新item字典时,假设n_items,它将替换B_1的值而不是将其设为B_1_1
n_items = {"C":7, "B":9}
items.update((k + '_1' if k in items else k, v) for k, v in n_items.items())
输出:
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 9, 'E': 8, 'C_1': 7}
但是我希望输出像这样:
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'B_1_1':9,'C_1_1':7}
或类似这样:
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'B_2':9,'C_2':7}
我该怎么办?
答案 0 :(得分:2)
您可以迭代地执行此操作:
def combine(*args):
result = {}
for d in args:
for key, value in d.items():
key = str(key)
while key in result:
key += '_1'
result[key] = value
return result
print(combine(items, u_items, n_items))
输出:
{'A': 1,
'B': 2,
'C': 3,
'D': 4,
'B_1': 4,
'E': 8,
'C_1': 4,
'C_1_1': 7,
'B_1_1': 9}
答案 1 :(得分:1)
尽管这似乎有点像 XY问题,但这是一个丑陋的问题(我很确定,效率很低),而且不是由以下组成的通用解决方案:
合并字典,方法是根据您的要求,在现有键上附加“ _1 ”(一行完成),尽管我建议(由于某些情况下最短的不一定是最好的):
>>> items = {"A": 1, "B": 2, "C": 3} >>> u_items = {"D": 4, "B": 4, "E": 8, "C": 4} >>> n_items = {"C": 7, "B": 9} >>> >>> items.update((max([k1 + "_1" for k1 in items if k1 == k or k1.startswith(k + "_1")], key=len, default=k), v) for k, v in u_items.items()) >>> items {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4} >>> >>> items.update((max([k1 + "_1" for k1 in items if k1 == k or k1.startswith(k + "_1")], key=len, default=k), v) for k, v in n_items.items()) >>> items {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'C_1_1': 7, 'B_1_1': 9} >>> >>> >>> # Merging an additional dictionary ... >>> v_items = {"C": 25} >>> >>> items.update((max([k1 + "_1" for k1 in items if k1 == k or k1.startswith(k + "_1")], key=len, default=k), v) for k, v in v_items.items()) >>> items {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'C_1_1': 7, 'B_1_1': 9, 'C_1_1_1': 25}
答案 2 :(得分:0)
使用operator.itemgetter
:
items = {'A':1, 'B':2, 'C':3}
u_items = {'D':4, 'B':4, 'E':8, 'C':4}
n_items = {"C":7, "B":9}
def update_dict(d1, d2):
l = list(map(itemgetter(0), d1))
d1.update(('_'.join([k,str(l.count(k))]) if k in l else k, v)
for k,v in d2.items())
update_dict(items, u_items)
update_dict(items, n_items)
使用u_items
进行第一次更新时的输出:
{'A': 1, 'B': 2, 'B_1': 4, 'C': 3, 'C_1': 4, 'D': 4, 'E': 8}
使用n_items
在第二次更新时输出:
{'A': 1,
'B': 2,
'B_1': 4,
'B_2': 9,
'C': 3,
'C_1': 4,
'C_2': 7,
'D': 4,
'E': 8}
答案 3 :(得分:0)
您可以使用一个小的助手功能:
d1 = {'A':1, 'B':2, 'B_1':3, 'B_1_1':4}
d2 = {'A':1, 'B':2}
def gen_key(key, dct):
while key in dct:
key += '_1'
return key
d1.update((gen_key(k, d1), v) for k, v in d2.items())
print(d1)
# {'A': 1, 'B': 2, 'B_1': 3, 'B_1_1': 4, 'A_1': 1, 'B_1_1_1': 2}
答案 4 :(得分:0)
发布者的更新方法和if / else列表理解是一个很好的开始。 我认为关键是(请问双关语)是引入一个循环来找到可以接受的密钥。它是python3,但可以为此而复活化简,使其成为单线:
>>> import functools
>>> items = {"A": 1, "B": 2, "C": 3}
>>> u_items = {"D": 4, "B": 4, "E": 8, "C": 4}
>>> n_items = {"C":7, "B":9}
>>> items.update({functools.reduce(lambda c, n: c+n if c in items else c, ['_1']*2, k):*3 v for k, v in u_items.items()})
>>> items
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4}
>>> items.update({functools.reduce(lambda c,n: c+n if c in items else c, ['_1']*2, k): v for k, v in n_items.items()})
>>> items
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'C_1_1': 7, 'B_1_1': 9}
请注意-渐进扩展名['_1']*2
的列表必须与您要合并的列表数一样长。如果需要像C_1, C_2, ...
这样的键,则可以构造一个更有趣的lambda。
答案 5 :(得分:0)
尝试一下
没有功能,没有任何模块,
>>> for k, v in n_items.items():
... _k = {k: v}
... if k in items:
... _k = {max(i for i in items if k in i)+'_1': v}
... items.update(_k)
...
>>> items
{'A': 1, 'D': 4, 'B_1': 4, 'B': 2, 'D_1': 5, 'X': 1, 'C_1_1': 7, 'C': 3, 'E': 8, 'C_1': 4, 'B_1_1': 9}
>>>
答案 6 :(得分:0)
由于我们通过添加 _count 来处理重复项,例如 next 是 C_1 我们只需要检查第一个字符 lambda x:x.startswith(key[0]) 基本上遍历 result.keys() 并检查是否有任何共享第一个字符 所以如果键有 C 和 C_1 ,我们会得到一个 2 的列表 一旦我们有了那个,该列表的长度将是下一个 C 的计数,即 len('C', 'C_1') 是 2,因此接下来我们有 'C_2'
def combine(*args):
result = {}
for d in args:
for key, value in d.items():
key = str(key)
if key in result:
keys = filter( lambda x:x.startswith(key[0]), result.keys())
keys = len(list(keys))
key = f'{key}_{keys}'
result[key] = value
return result
items = {"A": 1, "B": 2, "C": 3}
u_items = {"D": 4, "B": 4, "E": 8, "C": 4}
n_items = {"C":7, "B":9}
print(combine(items, u_items, n_items))
{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'B_1': 4, 'E': 8, 'C_1': 4, 'C_2': 7, 'B_2': 9}
[Program finished]