合并两个词典列表

时间:2017-02-03 06:55:55

标签: python list dictionary

[{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]

使用此词典列表, 我如何组合相同的键?

[{"APPLE": ["RED","GREEN"]}, {"BANANA": ["YELLOW", "GREEN"]}]

我想得到这个结果。

5 个答案:

答案 0 :(得分:2)

您可以通过创建中间词典来存储映射(甚至更好地使用collections.defaultdict,以达到所需格式list

from collections import defaultdict

my_list = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
temp_dict = defaultdict(list)

for item in my_list:
    for k, v in item.items():
        temp_dict[k] += v

# content of `temp_dict` is:
#     {
#          'APPLE': ['RED', 'GREEN'], 
#          'BANANA': ['YELLOW', 'GREEN']
#     }

要将dict转换为所需格式的列表,您可以使用列表理解表达式:

>>> new_list = [{k: v} for k, v in temp_dict.items()]
>>> new_list
[{'APPLE': ['RED', 'GREEN']}, {'BANANA': ['YELLOW', 'GREEN']}]

答案 1 :(得分:2)

不导入任何模块,

a = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
temp = {}
for i in a:
    for key in i:
        if key in temp.keys():
            temp[key].extend(i[key])
        else:
            temp[key] = i[key]
# print(temp)
op = [{key:val} for key,val in temp.items()]
print(op)

答案 2 :(得分:1)

您可以执行以下操作。只需遍历列表中的每个字典,然后添加键和所有值,如果已经添加了一个键,那么它将只使用其他值扩展列表。

from collections import OrderedDict

data = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]

temp = OrderedDict() # use ordered dict if you want to maintain order
# collapse dicts from data
for d in data:
    for key in d:
        temp.setdefault(key, []).extend(d[key])

res = [ { k : v } for k, v in temp.items() ] # split back into individual dicts
print(res)

# Output
[{'APPLE': ['RED', 'GREEN']}, {'BANANA': ['YELLOW', 'GREEN']}]

答案 3 :(得分:1)

如果您不需要易于阅读的代码,可以使用:

data = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]

keys = {key for keylist in [item.keys() for item in data] for key in keylist}
temp = {k: [color for item in data if k in item.keys() for color in item[k]] for k in keys}
rslt = [{k: v} for k, v in temp.items()]
print(rslt)

>>> [{'APPLE': ['RED', 'GREEN']}, {'BANANA': ['YELLOW', 'GREEN']}]

提示: 不要太认真。我很好奇尽可能多地进行内联。你甚至可以更进一步,将理解融入另一个......

rslt = [{k: v} for k, v in {k: [color for item in data if k in item.keys() for color in item[k]] for k in {key for keylist in [item.keys() for item in data] for key in keylist}}.items()]

就这种情况而言,您希望确保包括您在内的任何人都可以在一段时间后遵循此代码......;)

答案 4 :(得分:0)

与其他建议的解决方案类似,但使用reduce()函数。

定义一个帮助程序来合并字典并在reduce()函数中使用它

def ext(d1, d2):
  for k, v in d2.items():
    d1.setdefault(k, []).extend(v)
  return d1

src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
dst = reduce(ext, src, {})
print dst
>>> {'APPLE': ['RED', 'GREEN'], 'BANANA': ['YELLOW', 'GREEN']}

现在你有一个简洁的数据结构:一个字典,你可以对它做不同的查询。要获得所需的输出:

print [ { k : v } for k, v in dst.items() ]
[{'APPLE': ['RED', 'GREEN']}, {'BANANA': ['YELLOW', 'GREEN']}]

出于好奇心,对列出的解决方案进行性能测试

简洁胜利(Natarajan),默默无闻失败(jbndir)(由于额外的临时副本)。

词典setdefault()函数不会显着改变性能,它会缩短代码,因此应该使用if else语句。

import timeit
from collections import defaultdict

def f0():
  src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
  dst = defaultdict(list)
  for item in src:
      for k, v in item.items():
          dst[k] += v

def ext(d1, d2):
  for k, v in d2.items():
    d1.setdefault(k, []).extend(v)
  return d1

def f1():
  src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
  dst = reduce(ext, src, {})

def f2():
  src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
  dst = {}
  for i in src:
    for key in i:
      if key in dst.keys():
        dst[key].extend(i[key])
      else:
        dst[key] = i[key]

def f3():
  src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
  dst = {}
  for i in src:
    for key in i:
      dst.setdefault(key, []).extend(i[key])

def f4():
  src = [{"APPLE": ["RED"]}, {"BANANA": ["YELLOW", "GREEN"]}, {"APPLE": ["GREEN"]}]
  keys = {key for keylist in [item.keys() for item in src] for key in keylist}
  temp = {k: [color for item in src if k in item.keys() for color in item[k]] for k in keys}


min(timeit.repeat(lambda: f0())):  4.64622211456
min(timeit.repeat(lambda: f1())):  4.51267290115
min(timeit.repeat(lambda: f2())):  3.18728780746
min(timeit.repeat(lambda: f3())):  3.35215997696
min(timeit.repeat(lambda: f4())):  6.80625200272