合并词典时覆盖

时间:2017-02-20 18:52:59

标签: python dictionary

假设我们有2个词典,第一个是使用openpyxl从名为excel2013.xlsx的文件中提取的,第二个是来自excel2014.xlsx:

d1={'nume': 'Barta', 'cifra afaceri': 200, 'cifra2': 24}
d2={'nume': 'Barta', 'cifra afaceri': 190, 'cifra3': 21}

这些词典是词典列表的一部分。

lista=[{'nume': 'Barta', 'cifra afaceri': 200, 'cifra2': 24},{'nume': 'Barta', 'cifra afaceri': 190, 'cifra3': 21}]

首先,我想要做的是查看此列表,并根据一个键找到重复项,在本例中为密钥“nume”。从这些重复项中,我需要获取一个包含d1和d2中所有键的新字典。我的解决方案是:

import os
import itertools
ultima_lista=[]
ultima=[]
for a, b in itertools.combinations(lista,2):
    if a['nume'] == b['nume']:
        z=dict(list(a.items())+ list(b.items()))
        ultima_lista.append(z)
print(*ultima_lista, sep='\n')
print('------------------------------------------------------------------------------------------------------')
for a in lista:
    for b in ultima_lista:
        if a['nume'] == b['nume']:
            ultima.append(a)
print (*ultima, sep='\n')
print('------------------------------------------------------------------------------------------------------')
for i in ultima_lista:
    lista.append(i)
for i in ultima:
    lista.remove(i)
print(*lista, sep='\n')

现在这个解决方案是为了一个更大的列表,我们这里只有2个dicts。但是,使用这种方法我无法控制数据被覆盖的关键'cifra afaceri' - 从dict1或dict2中保留哪些数据。在这个例子中,我需要最新的信息,excel2014在顶部,这意味着我想要的输出应该是:

lista=[{'nume': 'Barta', 'cifra afaceri': 190, 'cifra2': 24,'cifra3': 21 }

我正在考虑制作另一个词典,其中键是'lista'中的元素,值是我从文件名中提取的年份.Ideas?| Thx

3 个答案:

答案 0 :(得分:0)

可能将列表作为字典中的值并附加每个字典中的值。这样,具有相同键的值将在列表中。除此之外,您循环的最后一个字典将附加到列表的末尾,以便您可以将其用作"优先级"。

d1={'nume': 'Barta', 'cifra afaceri': 200, 'cifra2': 24}
d2={'nume': 'Barta', 'cifra afaceri': 190, 'cifra3': 21}
result=dict()

for key, value in d1.items():
    if key in result:
        result[key].append(value)
    else:
        result[key] = [value]

for key, value in d2.items():
    if key in result:
        result[key].append(value)
    else:
        result[key] = [value]

print(result)

>>> {'cifra afaceri': [200, 190], 'cifra2': [24], 'cifra3': [21], 'nume': ['Barta', 'Barta']}

修改

如果您不需要重复键的先前值,则可以使用update作为问题评论中的建议者。您只需要使用最高优先级进行更新(例如,上次更新应该是最新的Excel工作表,因此它们的值优先。)

d1={'nume': 'Barta', 'cifra afaceri': 200, 'cifra2': 24}
d2={'nume': 'Barta', 'cifra afaceri': 190, 'cifra3': 21}
d3={'something': 'Barta', 'something else': 198, 'cifra3': 100}
result=dict()

# The order here is the priority, last update ends up with its value
# for the given key if duplicates
d1.update(d2)
d1.update(d3)

print(d1)

>>> {'cifra2': 24, 'cifra afaceri': 190, 'nume': 'Barta', 'something else': 198, 'something': 'Barta', 'cifra3': 100}

答案 1 :(得分:0)

首先groupbynume如何,然后再进行dict更新:

from itertools import groupby

d = [{'nume': 'Barta', 'cifra afaceri': 200, 'cifra2': 24}, 
     {'nume': 'Barta', 'cifra afaceri': 190, 'cifra3': 21}, 
     {'nume': 'Daniel', 'cifra afaceri': 190, 'cifra3': 21}]

d_all = list()
for key, group in groupby(d, key=lambda x: x['nume']):
    d_update = dict()
    for d in group:
        d_update.update(d)
    d_all.append(d_update)

输出如下:

[{'cifra afaceri': 190, 'cifra2': 24, 'cifra3': 21, 'nume': 'Barta'},
 {'cifra afaceri': 190, 'cifra3': 21, 'nume': 'Daniel'}]

答案 2 :(得分:0)

这个怎么样?

import itertools

temp = [x.items() for x in lista if x['nume'] == 'Barta']
flattened_temp = list(itertools.chain.from_iterable(temp))

d1_and_d2_keys = set(d1.keys() + d2.keys())    

sub_answer = {k: v for k, v in flattened_temp if k in d1_and_d2_keys}

sub_answer['cifra afaceri'] = d2['cifra afaceri']