簡體   English   中英

合並兩個字典列表

[英]Combine two lists of dictionaries

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

使用此詞典列表,如何組合相同的鍵?

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

我想得到這個結果。

您可以通過創建中間字典將映射存儲為所需格式的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']
#     }

要將dict轉換為所需格式的列表,可以將列表理解表達式用作:

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

無需導入任何模塊,

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)

您可以執行以下操作。 只需遍歷列表中的每個字典,然后添加鍵和所有值,如果已經添加了鍵,則它將使用其他值擴展列表。

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

如果您不需要易於閱讀的代碼,則可以使用:

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

僅在您要確保沒有任何人(包括您)可以在一段時間后遵循此代碼的情況下...;)

與其他建議的解決方案類似,但使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM