合并多个dicts列表,添加重复值和排序值

时间:2018-04-27 13:07:23

标签: python python-3.x

我有3个字典列表,我想合并和排序。如果同一个_id的dict不止一个,则应删除副本,但应将count_enabledcount_disabled的值添加(总和)到剩余的一个。这些列表可能有也可能没有重复,长度不同

Foo = [
   {'_id': 'core.system', 'count_enabled': 9, 'count_disabled': 0},
   {'_id': 'core.system', 'count_enabled': 0, 'count_disabled': 0}, 
   {'_id': 'core.private_channel', 'count_enabled': 4, 'count_disabled': 0}]
Bar = [
   {'_id': 'core.admin', 'count_enabled': 9, 'count_disabled': 0},
   {'_id': 'core.colors', 'count_enabled': 0, 'count_disabled': 0},
   {'_id': 'core.system', 'count_enabled': 0, 'count_disabled': 0}]
Baz = [
  {'_id': 'core.system', 'count_enabled': 0, 'count_disabled': 0},
  {'_id': 'core.whois', 'count_enabled': 9, 'count_disabled': 0}]

这是我到目前为止所做的:

data = []
for i in [Foo,Bar,Baz]:
    for j in i:
        data.append({'module':j['_id'], 'count_enabled' : j['count_enabled'], 'count_disabled': j['count_disabled']})

sort = sorted(data, key=itemgetter('module'))

我也将_id重命名为module,但这不是很重要,data已正确排序,唯一剩下的就是删除重复项并添加其值。

3 个答案:

答案 0 :(得分:1)

除了排序,我认为将所有词典合并到最终列表中可以使用下面的代码完成。

我基本上为唯一字典条目创建了final_list

对于dict的每个list,我遍历final_dict中的字典条目(final_list)。如果我找到包含当前final_dict的{​​{1}},我会对这些值进行求和,然后突破内部for循环以继续_id中的下一个dict

如果我在任何list中找不到_id,我会将该词典附加到最终列表中。

final_dict

答案 1 :(得分:0)

我有点不清楚你最终希望在这里生产什么。但我会假设它是一个排序的dicts列表,其中每个dict只有三个键。我假设你有理由,但这是一个非常尴尬的结构。为什么不关键_id / module

类似的东西:

enabled = dict()
disabled = dict()
for i in (Foo, Bar, Baz):
    enabled[i[module]] = enabled.get(i[module], 0) + i['count_enabled']
    disabled[i[module]] = disabled.get(i[module], 0) + i['count_disabled']

results = [{'module': m, 'count_enabled': enabled[m], 'count_disabled': disabled[m]} for m in sorted(enabled.keys())]

答案 2 :(得分:0)

或者,您可以使用Python的集合,特别是defaultdictreduce()来合并字典。

import collections
import functools

# Group the dictionaries by '_id'.
records = collections.defaultdict(list)
for record in [*Foo, *Bar, *Baz]:
    id = record['_id']
    record.pop('_id', None)
    records[id].append(record)

# Combine the dictionaries from each group.
data = []
for key, value in records.items():
    data.append({ **{'_id': key, },
        **dict(functools.reduce(
            lambda x, y: x.update(y),
            [collections.Counter(x) for x in value]
        ))}
    )

print(data)

请务必注意,运行上面的代码会导致删除任何具有非零值的键。如果要保持键具有非零值,可以使用以下代码替换最后一个for循环。

data = []
for key, value in records.items():
    combined_values = collections.Counter()
    for d in value:
        combined_values.update(d)        

    data.append({ **{'_id': key, }, **combined_values )}
)