1. 前言 Python 的字典(dict)是一種非常方便的資料結構,用來以鍵值對的形式管理資料。在實務中,常常會需要合併多個字典,例如整合多個設定檔,或是彙總來自不同資料集的資訊。 本文將詳細介紹在 Python 中合併字典的多種方法。內容涵蓋從初學者到中階使用者,包含基本技巧、Python 3.9 新增的寫法,甚至是應對特殊情況的進階技巧。我們會透過程式碼範例,幫助你了解每種方法的特性與使用場景,找到最適合自己的合併方式。
2. 字典合併的基本方法 在 Python 中,有多種方法可以用來合併字典。我們先從最基本的幾種方式開始介紹。2.1 使用 update()
方法 特點 update()
方法是最基本的字典合併方式,會將另一個字典的內容加入到原本的字典中。這是一種破壞性操作(會改變原本的字典),因此若需要保留原始資料,使用時要特別注意。程式碼範例 dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
dict1.update(dict2)
print(dict1) # {'a': 1, 'b': 3, 'c': 4}
說明 上述程式碼中,dict2
的內容被合併到 dict1
。若有重複的鍵(例如 'b'
),會以後面字典(這裡是 dict2
)的值為主進行覆蓋。適用情境 不介意修改原本的字典。 需要簡單且效率高的合併方法時。 2.2 使用解包運算子(**
) 特點 從 Python 3.5 起,可以使用解包運算子(**
)來合併字典。這是一種非破壞性操作,會建立新的字典而不改變原始資料。程式碼範例 dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined_dict = {**dict1, **dict2}
print(combined_dict) # {'a': 1, 'b': 3, 'c': 4}
說明 這個方法會將多個字典展開後合併為新的字典。若有重複的鍵,會使用後面字典(dict2
)的值進行覆蓋。適用情境 需要保留原始字典內容。 希望程式碼具有良好的可讀性。 2.3 使用合併運算子(|
) 特點 從 Python 3.9 開始,可以使用 |
運算子簡潔地合併字典。這也是非破壞性操作,會建立新的字典。程式碼範例 dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined_dict = dict1 | dict2
print(combined_dict) # {'a': 1, 'b': 3, 'c': 4}
說明 這種寫法更加直觀,讓程式碼更易讀,也更適合 Python 初學者理解。適用情境 使用 Python 3.9 或以上版本時。 希望程式碼簡潔且容易維護。 3. 特殊情況下的字典合併方式 在掌握基本的字典合併方法後,接下來我們來看看一些特殊情況或進階的合併技巧。這些方法在特定需求下非常實用,適合處理更複雜的場景。3.1 使用 dict()
建構子 特點 這種方法是利用 dict()
建構子來合併多個字典。當你需要在合併時額外新增鍵值對,或是包含展開過的字典時,這種寫法會非常方便。程式碼範例 dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3}
combined_dict = dict(dict1, **dict2)
print(combined_dict) # {'a': 1, 'b': 2, 'c': 3}
說明 dict1
作為基礎,dict2
的內容被展開後合併進來。注意:由於使用了 **
運算子,dict2
的鍵必須是字串,否則會出錯。 適用情境 在基本合併的同時想加入額外的鍵值對。 需要 Python 3.5 或以上版本。 3.2 使用 collections.ChainMap
特點 ChainMap
是 Python 標準函式庫中 collections
模組提供的工具,適用於暫時性地整合多個字典。這種方式並不會真正合併字典,而是保留原始字典的結構。程式碼範例 from collections import ChainMap
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined = ChainMap(dict1, dict2)
print(combined['b']) # 2
print(combined['c']) # 4
說明 ChainMap
可以將多個字典視為一個虛擬的整體。在查找鍵時,會優先從最前面的字典中搜尋。本例中,'b'
的值來自 dict1
(值為 2
)。 適用情境 不希望實際合併字典,而是動態處理資料時。 處理大量資料時,希望節省記憶體資源。
4. 合併字典時的注意事項 在合併字典的過程中,有幾個需要特別注意的地方。了解這些細節能幫助你避免錯誤與資料不一致的問題。4.1 鍵值重複時的行為 當兩個字典中存在重複鍵時,合併後會以後面字典中的值為主,進行覆蓋。範例 dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined = {**dict1, **dict2}
print(combined) # {'a': 1, 'b': 3, 'c': 4}
這個例子中,鍵 'b'
的值被 dict2
中的 3
覆蓋了原本 dict1
的 2
。了解這種行為是非常重要的。4.2 不同方法的效能差異 不同的合併方法在效能上可能會有所差異,特別是當資料量很大時,更需要注意選擇最合適的方式。效能比較(概略) update()
方法 :效能高,但會改變原始字典,若需保留備份不適合。解包運算子(**
) :不會改變原始資料,較方便但在大量資料情況下記憶體使用可能增加。ChainMap
:不會真正合併資料,記憶體使用效率高,適合處理大量資料。5. 各種字典合併方法的比較與選擇指南 這一節將比較不同的字典合併方法,幫助你根據實際情況選擇最合適的方式。5.1 方法比較表 方法 是否破壞原資料 支援版本 重複鍵的行為 效能 update()
破壞性 所有版本 以後方字典為主 高 解包運算子(**
) 非破壞性 3.5 以後 以後方字典為主 中等 合併運算子(|
) 非破壞性 3.9 以後 以後方字典為主 中等 ChainMap
非破壞性 所有版本 以前方字典為主 高(記憶體效率)
5.2 選擇建議 如果使用的是 Python 3.9 或以上版本: 推薦使用最簡潔且可讀性高的 |
運算子。 如果使用的是 Python 3.5 到 3.8: 可以選擇使用解包運算子(**
)。 若需要處理大量資料或重視記憶體使用效率: ChainMap
是最佳選擇。若可以接受改變原始字典內容: update()
方法是高效且簡單的方案。
6. 常見問題(FAQ) 本節將解答讀者在合併 Python 字典時常遇到的疑問,包括錯誤原因與特殊情境的對應方式。6.1 為什麼在合併字典時會出現錯誤? 錯誤範例 執行以下程式碼時會發生錯誤:dict1 = {'a': 1, 'b': 2}
dict2 = {('c',): 3}
combined_dict = {**dict1, **dict2}
錯誤原因 使用解包運算子(**
)時,字典的鍵必須是字串。如果鍵是非字串型別(像是 tuple),就會出現錯誤。在上述範例中,dict2
的鍵 ('c',)
是 tuple,因此導致錯誤。解決方法 如果鍵不是字串,可以改用 update()
方法,或使用迴圈手動合併:dict1 = {'a': 1, 'b': 2}
dict2 = {('c',): 3}
dict1.update(dict2) # 正常執行
print(dict1) # {'a': 1, 'b': 2, ('c',): 3}
6.2 若使用的是 Python 3.9 以下版本,該如何替代 |
運算子? 解答 在 Python 3.9 以下的版本中雖然無法使用 |
運算子,但可以使用解包運算子(**
)達到相同效果。範例 即使是 Python 3.8 或更早的版本,也可以使用以下寫法:dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined_dict = {**dict1, **dict2}
print(combined_dict) # {'a': 1, 'b': 3, 'c': 4}
6.3 若字典中包含巢狀結構,要如何合併? 問題說明 當合併的是巢狀字典時,單純使用 **
或 |
會導致資料被覆蓋,而不是進行深層合併:dict1 = {'a': {'x': 1}}
dict2 = {'a': {'y': 2}}
combined_dict = {**dict1, **dict2}
print(combined_dict) # {'a': {'y': 2}}
如上例,dict2
的值覆蓋了 dict1
中的 'a'
鍵,導致原本的資料被移除。解決方法 需要使用遞迴函式來進行深層合併:def merge_dicts(d1, d2):
result = d1.copy()
for key, value in d2.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = merge_dicts(result[key], value)
else:
result[key] = value
return result
dict1 = {'a': {'x': 1}}
dict2 = {'a': {'y': 2}}
combined_dict = merge_dicts(dict1, dict2)
print(combined_dict) # {'a': {'x': 1, 'y': 2}}
6.4 可以一次合併多個字典嗎? 解答 在 Python 3.9 之後,你可以使用多個 |
運算子連續合併多個字典:範例 dict1 = {'a': 1}
dict2 = {'b': 2}
dict3 = {'c': 3}
combined_dict = dict1 | dict2 | dict3
print(combined_dict) # {'a': 1, 'b': 2, 'c': 3}
如果是舊版本,也可以使用多個解包運算子:combined_dict = {**dict1, **dict2, **dict3}
print(combined_dict) # {'a': 1, 'b': 2, 'c': 3}
6.5 處理大量資料時,哪種合併方式最有效? 解答 當資料量龐大時,使用 ChainMap
是一種高效選擇,因為它不會真正將字典合併,而是以串接方式進行查找,節省記憶體空間。範例 from collections import ChainMap
dict1 = {'a': 1}
dict2 = {'b': 2}
combined = ChainMap(dict1, dict2)
print(combined['a']) # 1
print(combined['b']) # 2
7. 總結 本文介紹了在 Python 中合併字典的各種方法,從基本到進階,並搭配範例說明,讓初學者也能輕鬆理解。重點回顧 update()
方法 是一種簡單且效率高的方式,但會改變原始字典。解包運算子(**
) 是非破壞性方法,適合建立新字典。合併運算子(|
) 適用於 Python 3.9 之後,語法簡潔且易讀。ChainMap
適合處理大量資料,並具有優異的記憶體效率。 每種方法都有其優點與適用場景,建議根據實際需求與 Python 的版本來選擇。例如:若需處理巢狀結構、重複鍵、或大量資料,應特別考慮適合的合併策略。 未來在實際專案中遇到字典合併需求時,歡迎參考本文提供的方法,多嘗試實作將有助於加深理解。此外,也推薦閱讀本站其他與 Python 資料處理相關的教學內容!