【问题标题】:Merge multiple dicts with same key-value pair to one dict python将具有相同键值对的多个字典合并到一个字典 python
【发布时间】:2019-09-18 21:06:37
【问题描述】:

我有一个存储在列表中的字典列表。我想将相同的字典合并为一个。我有三个领域。 Task_id 提供要检查的字段。 value 是该字段的值。首先,它检查字典中的值,并为要合并的字典创建一个新字典。如果所有值都相同并且其中一个值不同,则它将字典合并为一个。如何让它成为可能

这是我尝试过的示例代码:

field_to_be_check ="state"
merger = ["city", "ads"]
merge_name = ["cities", "my_ads"]

data = [
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tirunelveli'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad4', 'city': 'nagerkoil'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tuticorin'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'madurai'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'chennai'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'palakad'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'guruvayor'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kolikodu'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kottayam'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'idukki'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Akola'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Washim'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Jalna'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Nanded'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Latur'}
]

d = []
list1 = []
for item in data:
    value = item[field_to_be_check]
    inserted = False
    for l in list1: 
        if l[field_to_be_check] == value:
            inserted = True
            for m_name in merge_name:

    if inserted == False:
        list1.append(item)

print(list1)

所需输出:

   [
    {'state': 'tamil nadu','my_ads':[{'ads': 'ad1'},{'ads': 'ad4'}], 'cities':[{'city': 'tirunelveli'},{'city': 'nagerkoil'},{'city': 'tuticorin'},{'city': 'madurai'},{'city': 'chennai'}]}, 
    {'state': 'kerala',,'my_ads':[{'ads': 'ad2'}], 'cities': [{'city': 'palakad'},{'city': 'guruvayor'},{'city': 'kolikodu'},{'city': 'kottayam'},{'city': 'idukki'}]}, 
    {'state': 'mumbai', 'my_ads':[{'ads': 'ad3'}],'cities':[{'city': 'Akola'},{'city': 'Washim'},{'city': 'Jalna'},{'city': 'Nanded'},{'city': 'Latur'}]}
    ]

【问题讨论】:

  • 您不需要'cities' 'city' 键,具体取决于有多少个城市。你总是想要一个'cities' 键,它有时只有一个城市。
  • 为什么要区分city kerla,它没有按照你在输出中说的模式?
  • 在值字段中,我已经给出了条件。表明,它应该只检查这两个状态。如果它在那里,它应该合并城市并将其合并为一个并分配给目标城市
  • 改变了我需要的输出......
  • 是否保证hapsads 的值对于每个state 总是相同的?如果不是呢?

标签: python python-3.x dictionary for-loop


【解决方案1】:

这是看到itertools.groupby力量的完美场景 请注意,我假设 haps、state 和 ads 将出现在所有字典中,并且重复相似

from itertools import groupby

field_to_be_check =  "state"
merger = ["city", "ads"]
merge_name = ["cities", "my_ads"]

data = [
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tirunelveli'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad4', 'city': 'nagerkoil'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tuticorin'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'madurai'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'chennai'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'palakad'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'guruvayor'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kolikodu'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kottayam'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'idukki'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Akola'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Washim'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Jalna'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Nanded'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Latur'}
]

#Function to make the merger lists
def process_group(group, merger_item):

    item_set = set()
    item_list = []
    for item in group:
        item_set.add(item[merger_item])

    for item in item_set:
        item_list.append({merger_item: item})

    return item_list

#Group on haps, state and ads
grp = groupby(data,key=lambda x:(x[field_to_be_check]))
result = []

#Iterate through the group and build your result list
for model, group in grp:
    cities_dict = {}

    cities_dict[field_to_be_check] = model

    group_list = list(group)

    #Make the list for merger fields
    for idx, name in enumerate(merger):
        cities_dict[merge_name[idx]] = process_group(group_list, name)

    result.append(cities_dict)

print(result)

输出看起来像

[{'state': 'tamil nadu', 
'cities': [{'city': 'nagerkoil'}, {'city': 'tuticorin'}, {'city': 'chennai'}, {'city': 'madurai'}, {'city': 'tirunelveli'}], 
'my_ads': [{'ads': 'ad4'}, {'ads': 'ad1'}]}, 
{'state': 'kerala', 
'cities': [{'city': 'guruvayor'}, {'city': 'idukki'}, {'city': 'kottayam'}, {'city': 'palakad'}, {'city': 'kolikodu'}], 
'my_ads': [{'ads': 'ad2'}]}, 
{'state': 'mumbai', 
'cities': [{'city': 'Jalna'}, {'city': 'Nanded'}, {'city': 'Washim'}, {'city': 'Latur'}, {'city': 'Akola'}], 
'my_ads': [{'ads': 'ad3'}]}]

【讨论】:

  • 谢谢。有效。但我已经修改了合并多个字典的问题,并在开始时添加了 3 个不同的文件。是否有可能获得有关该问题的所需输出。
  • 谢谢你。但我想根据以上三个字段进行合并。在“field_to_be_check ="state"”中,我将设置要分组的值。在合并中,我将设置要合并的字段,并在“merge_name = [“cities”,“my_ads”]”中,将合并后的值分配给字典。这 3 个由用户处理。用户可以在“合并”中提供他希望合并的任何字段。如何使其成为可能。
  • 其实你在hapsstate上进行分组,在最新的例子中合并cityads,你同意吗?
  • 我正在与州分组。然后我根据用户的意愿合并城市和广告。
  • 不,您实际上是在 hapsstate 上进行分组,只是所有字典的 haps 和 state 的值最终都相同,请再次检查!
【解决方案2】:
field_to_be_check ="state"
merger = ["city", "ads"]
merge_name = ["cities", "my_ads"]

data = [
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tirunelveli'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad4', 'city': 'nagerkoil'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tuticorin'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'madurai'}, 
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'chennai'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'palakad'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'guruvayor'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kolikodu'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kottayam'}, 
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'idukki'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Akola'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Washim'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Jalna'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Nanded'}, 
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Latur'}
]
# merger and merge_name must be one to one.
the_dict = {m:mn for m, mn in zip(merger, merge_name)}
# {"city":"cities", "ads":"my_ads"}  merge_name
newdata = data.copy()
# create new_ret as result
new_ret = [{field_to_be_check:i, **{i:[] for i in merge_name}} for i in set([i[field_to_be_check] for i in data])]
# print(new_ret, "this is new_ret")
for val in new_ret:
    for k in newdata:
        if val[field_to_be_check] != k[field_to_be_check]:
            continue
        tmp = {i:k[i] for i in merger}
        for single in tmp:
            if {single:tmp[single]} not in val[the_dict[single]]:
                val[the_dict[single]].append({single:tmp[single]})
print(new_ret)

【讨论】:

  • 这段代码可能不好,我认为它可以解决你的问题。试试看?
  • 这个代码对我不起作用,你能解释一下吗!
  • 谢谢。有效。但我已经修改了合并多个字典的问题,并在开始时添加了 3 个不同的文件。是否有可能获得有关该问题的所需输出。
  • 我更新了问题代码,可能不好读。你可以试试@Smack Alpha
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多