简体   繁体   English

合并两个字典列表

[英]Combine two lists of dictionaries

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

Using this list of dictionaries, how can i combine same keys? 使用此词典列表,如何组合相同的键?

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

I want to get this result. 我想得到这个结果。

You may achieve the list in desired format via creating intermediate dictionary to store the mapping (even better to use collections.defaultdict ) as: 您可以通过创建中间字典将映射存储为所需格式的list ,以将映射存储为(最好使用collections.defaultdict为:

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']
#     }

For converting the dict to the list of desired format, you may use a list comprehension expression as: 要将dict转换为所需格式的列表,可以将列表理解表达式用作:

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

Without importing any modules, 无需导入任何模块,

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)

You can do the following. 您可以执行以下操作。 Simply iterate through each dictionary in your list and then add the key and all values, if a key has already been added then it will just extend the list with the other values. 只需遍历列表中的每个字典,然后添加键和所有值,如果已经添加了键,则它将使用其他值扩展列表。

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']}]

If you don't need easily readable code, you may use: 如果您不需要易于阅读的代码,则可以使用:

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']}]

Hint: Don't take this too serious. 提示: 不要太认真。 I was just curious about doing as much inline as possible. 我只是想做尽可能多的内联。 You could even go further and nest the comprehensions into another... 您甚至可以走得更远,将理解力嵌套到另一个...

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()]

Just for the case you want to make sure that nobody, including you, can follow this code after a while... ;) 仅在您要确保没有任何人(包括您)可以在一段时间后遵循此代码的情况下...;)

Similar to other suggested solutions but using reduce() function. 与其他建议的解决方案类似,但使用reduce()函数。

Define a helper to merge dictionaries and use it in reduce() function 定义一个合并字典的助手,并在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']}

Now you have a succinct data structure: a dictionary and you can do different queries on it. 现在,您有了一个简洁的数据结构:一个字典,您可以对其进行不同的查询。 To get the desired output: 要获得所需的输出:

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

Out of curiosity run performance tests of listed solutions 出于好奇,对列出的解决方案进行了性能测试

Simplicity wins ( Natarajan ), obscurity fails behind ( jbndir ) (due to additional temporary copies). 简洁胜出( Natarajan ),晦涩失败( jbndir )(由于额外的临时副本)。

Dictionary setdefault() function doesn't change the performance noticeably, it shortens code, so should be used instead of if else statement. 字典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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM