Python數(shù)據(jù)整合:基于鍵值匹配高效合并字典列表

Python數(shù)據(jù)整合:基于鍵值匹配高效合并字典列表

本教程詳細(xì)闡述了如何在python中高效地將多個(gè)字典列表進(jìn)行合并與數(shù)據(jù)補(bǔ)充。通過(guò)匹配特定鍵的值,我們可以將來(lái)自不同源列表(如listA和listB)的額外信息(如original_name和original_address)整合到主數(shù)據(jù)列表(dataList)的每個(gè)字典條目中,從而構(gòu)建一個(gè)包含所有所需字段的全新字典列表。本文將提供實(shí)用的代碼示例和最佳實(shí)踐,幫助讀者掌握此類數(shù)據(jù)整合技巧。

在數(shù)據(jù)處理過(guò)程中,我們經(jīng)常會(huì)遇到需要從多個(gè)數(shù)據(jù)源整合信息以構(gòu)建一個(gè)更完整數(shù)據(jù)集的場(chǎng)景。例如,你可能有一個(gè)包含核心記錄的列表,以及其他包含補(bǔ)充屬性的輔助列表。目標(biāo)是根據(jù)共同的標(biāo)識(shí)符(如名稱或地址)將這些補(bǔ)充屬性添加到核心記錄中。

場(chǎng)景描述與挑戰(zhàn)

假設(shè)我們有以下三個(gè)字典列表:

  • listA:包含 name 和 original_name,用于提供原始名稱信息。
  • listB:包含 address 和 original_address,用于提供原始地址信息。
  • dataList:主數(shù)據(jù)列表,包含 id, created_at, name, address 等核心信息。

我們的任務(wù)是創(chuàng)建一個(gè)新的列表 finalList,它基于 dataList,但同時(shí)從 listA 中匹配 name 字段,并添加 original_name;從 listB 中匹配 address 字段,并添加 original_address。

原始數(shù)據(jù)示例如下:

立即學(xué)習(xí)Python免費(fèi)學(xué)習(xí)筆記(深入)”;

listA = [   {     "name": "name sample 1",     "original_name" : "original name sample 1",   },   {     "name": "name sample 2",     "original_name" : "original name sample 2",   } ]  listB = [   {     "address": "address sample 1",     "original_address" : "original address sample 1",   },   {     "address": "address sample 2",     "original_address" : "original address sample 2",   } ]  dataList = [   {     "id": "1",     "created_at": "date 1",     "name": "name sample 1",     "address": "address sample 1",   },   {     "id": "2",     "created_at": "date 2",     "name": "name sample 2",     "address": "address sample 2",   } ]

期望的 finalList 結(jié)構(gòu)應(yīng)為:

finalList = [   {     "id": "1",     "created_at": "date 1",     "name": "name sample 1",     "original_name" : "original name sample 1",     "address": "address sample 1",     "original_address" : "original address sample 1",   },   {     "id": "2",     "created_at": "date 2",     "name": "name sample 2",     "original_name" : "original name sample 2",     "address": "address sample 2",     "original_address" : "original address sample 2",   } ]

解決方案:基于嵌套循環(huán)的匹配與更新

一種直觀且有效的方法是利用 Python 的循環(huán)結(jié)構(gòu),遍歷輔助列表,并在主列表中查找匹配項(xiàng)進(jìn)行更新。為了避免修改原始 dataList,我們首先創(chuàng)建一個(gè)它的深拷貝。

核心思路

  1. 復(fù)制主列表:使用 copy 模塊的 deepcopy 函數(shù)創(chuàng)建 dataList 的一個(gè)獨(dú)立副本,作為我們最終操作的 finalList。
  2. 合并輔助列表:將 listA 和 listB 合并成一個(gè)迭代器(通過(guò) listA + listB),這樣可以一次性處理所有補(bǔ)充數(shù)據(jù)。
  3. 遍歷并匹配更新
    • 對(duì)于合并后的每個(gè)輔助字典條目 (entry):
    • 判斷 entry 中包含的是 name 還是 address 鍵,以確定其來(lái)源。
    • 根據(jù)判斷結(jié)果,遍歷 finalList 中的每個(gè)字典 (data)。
    • 如果 data 中相應(yīng)的匹配鍵值與 entry 中的鍵值匹配,則將 entry 中對(duì)應(yīng)的 original_ 字段添加到 data 中。

示例代碼

from copy import deepcopy  # 原始數(shù)據(jù)定義 (與上述場(chǎng)景描述一致) listA = [   {"name": "name sample 1", "original_name" : "original name sample 1"},   {"name": "name sample 2", "original_name" : "original name sample 2"} ]  listB = [   {"address": "address sample 1", "original_address" : "original address sample 1"},   {"address": "address sample 2", "original_address" : "original address sample 2"} ]  dataList = [   {"id": "1", "created_at": "date 1", "name": "name sample 1", "address": "address sample 1"},   {"id": "2", "created_at": "date 2", "name": "name sample 2", "address": "address sample 2"} ]  # 1. 創(chuàng)建dataList的深拷貝,避免修改原始數(shù)據(jù) finalList = deepcopy(dataList)  # 2. 遍歷listA和listB的合并結(jié)果 # 這種方式巧妙地將兩個(gè)不同類型的補(bǔ)充數(shù)據(jù)統(tǒng)一處理 for entry in listA + listB:     # 3. 根據(jù)entry中存在的鍵(name或address)進(jìn)行判斷     if "name" in entry:         # 如果是來(lái)自listA的條目,則匹配name并添加original_name         for data in finalList:             if data['name'] == entry['name']:                 data['original_name'] = entry['original_name']     elif "address" in entry:         # 如果是來(lái)自listB的條目,則匹配address并添加original_address         for data in finalList:             if data['address'] == entry['address']:                 data['original_address'] = entry['original_address']  # 打印結(jié)果,驗(yàn)證原始dataList未被修改,且finalList已包含所需信息 print("原始dataList (未修改):") print(dataList) print("n合并后的finalList:") print(finalList)

運(yùn)行結(jié)果

原始dataList (未修改): [{'id': '1', 'created_at': 'date 1', 'name': 'name sample 1', 'address': 'address sample 1'}, {'id': '2', 'created_at': 'date 2', 'name': 'name sample 2', 'address': 'address sample 2'}]  合并后的finalList: [{'id': '1', 'created_at': 'date 1', 'name': 'name sample 1', 'address': 'address sample 1', 'original_name': 'original name sample 1', 'original_address': 'original address sample 1'}, {'id': '2', 'created_at': 'date 2', 'name': 'name sample 2', 'address': 'address sample 2', 'original_name': 'original name sample 2', 'original_address': 'original address sample 2'}]

注意事項(xiàng)與性能優(yōu)化

上述方法對(duì)于小規(guī)模數(shù)據(jù)是有效且易于理解的。然而,當(dāng)列表規(guī)模非常大時(shí),嵌套循環(huán)的性能會(huì)成為瓶頸。其時(shí)間復(fù)雜度為 O(M * N),其中 M 是 listA + listB 的總長(zhǎng)度,N 是 finalList 的長(zhǎng)度。對(duì)于大型數(shù)據(jù)集,可以考慮以下優(yōu)化策略:

1. 使用字典進(jìn)行預(yù)處理(哈希映射)

將輔助列表轉(zhuǎn)換為字典(哈希映射),以實(shí)現(xiàn) O(1) 的平均查找時(shí)間。這將把整體時(shí)間復(fù)雜度降低到 O(M + N),因?yàn)轭A(yù)處理和最終遍歷

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊15 分享