簡體   English   中英

如果值相同則合並兩個字典列表

[英]merge two dictionary lists if value is the same

我有兩個字典列表,如下所示:

a = [
    {'name': 'john', 'exam 1': 'python'},
    {'name': 'chris', 'exam 1': 'java'},
    {'name': 'newman', 'exam 1': 'C'},
    {'name': 'sebast', 'exam 1': 'C#'},
    {'name': 'penier', 'exam 1': 'python'},
    {'name': 'alex', 'exam 1': 'go'},
    {'name': 'steve', 'exam 1': 'C#'}
]

b = [
    {'name': 'john', 'exam 2': 'django'},
    {'name': 'newman', 'exam 2': 'java'},
    {'name': 'sebast', 'exam 2': 'C'},
    {'name': 'chris', 'exam 2': 'C#'}
    {'name': 'penier', 'exam 2': 'python'},
    {'name': 'steve', 'exam 2': 'go'},
    {'name': 'alex', 'exam 2': 'C#'}
]

我想將它們合並到一本字典中,如下所示:

c = [
    {'name': 'john', 'exam 1': 'python', 'exam 2': 'django'},
    {'name': 'chris', 'exam 1': 'java', 'exam 2': 'C#'},
    {'name': 'newman', 'exam 1': 'C', 'exam 2': 'java'},
    {'name': 'sebast', 'exam 1': 'C#', 'exam 2': 'C'},
    {'name': 'penier', 'exam 1': 'python', 'exam 2': 'python'},
    {'name': 'alex', 'exam 1': 'go', 'exam 2': 'C#'},
    {'name': 'steve', 'exam 1': 'C#', 'exam 2': 'go'}
]

我嘗試了以下方法:

for i, j in zip(a, b):
   if i['name'] == j['name']:
      c.update(i)

我得到的結果只是一本字典,如果它們的位置不同,則添加那些相同的行。

您可以為每個列表創建兩個查找詞典,然后找到交集

import pprint

lookup_A = {d["name"]: d for d in A}
lookup_B = {d["name"]: d for d in B}

result = [{**value, **lookup_B.get(key, {})} for key, value in lookup_A.items()]
pprint.pprint(result)

Output

[{'exam 1': 'python', 'exam 2': 'django', 'name': 'john'},
 {'exam 1': 'java', 'exam 2': 'C#', 'name': 'chris'},
 {'exam 1': 'C', 'exam 2': 'java', 'name': 'newman'},
 {'exam 1': 'C#', 'exam 2': 'C', 'name': 'sebast'},
 {'exam 1': 'python', 'exam 2': 'python', 'name': 'penier'},
 {'exam 1': 'go', 'exam 2': 'C#', 'name': 'alex'},
 {'exam 1': 'C#', 'exam 2': 'go', 'name': 'steve'}]

更新

理解列表理解的一種更簡單的方法是執行等效的 for 循環:

result= []
for key, value in lookup_A.items():
    result.append({**value, **lookup_B.get(key, {})})

表達方式:

{**value, **lookup_B.get(key, {})}

被稱為字典解包,它在3.5版本中被添加到 Python

使用pandas您可以進行merge

pd.DataFrame(A).merge(pd.DataFrame(B), on='name').to_dict('records')

[{'name': 'john', 'exam 1': 'python', 'exam 2': 'django'},
 {'name': 'chris', 'exam 1': 'java', 'exam 2': 'C#'},
 {'name': 'newman', 'exam 1': 'C', 'exam 2': 'java'},
 {'name': 'sebast', 'exam 1': 'C#', 'exam 2': 'C'},
 {'name': 'penier', 'exam 1': 'python', 'exam 2': 'python'},
 {'name': 'alex', 'exam 1': 'go', 'exam 2': 'C#'},
 {'name': 'steve', 'exam 1': 'C#', 'exam 2': 'go'}]

雖然效率低下,但這是一種易於遵循的簡單方法,我想您在嘗試使用zip時想到的就是這種方法。

for a in A:
    for b in B:
        if b['name'] == a['name']:
            a.update(b)
    C.append(a)

我會遍歷列表並在添加之前進行查找,如下所示:
好處是更好的控制。 成本是 O(n),其中 n 是b的長度

# Start off with values being a
c_dict = {x['name']:x for x in a}

# 'Upsert' from new list of dicts
for x in b:
    # You can update this to make this skip items not found in b
    # or other similar operations
    if not c_dict.get(x['name']):
         c_dict[x['name']] = x
    else:
        c_dict[x['name']].update(x)

# Finally convert to a list
c = list(c_dict.values())

暫無
暫無

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

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