如何在 Python 中複製一個字典
本教程討論瞭如何在 Python 中複製一個字典。
我們將用兩種方式演示如何複製一個字典:通過值傳遞和通過引用傳遞。
在 Python 中複製一個字典:通過引用傳遞
在 Python 中,物件不是隱式複製的。如果我們嘗試將 food
複製到一個新的變數 meal
中,food
的值將被複制到 meal
中,但 food
的引用也將被複制。
meal = food
將一個物件直接等價於另一個物件將使新物件指向前一個物件;這意味著兩個變數將引用同一個唯一的物件。
如果我們將 meal
中的 Fruit
值更新為 Banana
,food
中的 Fruit
值也將被替換。
meal['Fruit'] = 'Banana'
print(food)
print(meal)
輸出:
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
如果我們嘗試更新 meal
塊中的一個鍵,情況也是一樣。我們將用 Circle Fruit
替換鍵 Fruit
,並在將其彈出字典之前複製其值。
meal['Circle Fruit'] = meal.pop('Fruit')
print(food)
print(meal)
輸出:
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
即使我們沒有直接修改 food
的值,它仍然會被替換;這是因為我們用來複制 food
到 meal
的方法是通過引用傳遞的。
在 Python 中複製一個字典:通過值傳遞
通過值傳遞意味著將在記憶體中建立一個實際的物件副本,而不是在複製一個物件時將副本指向原始物件。
如果我們想複製一個字典,避免引用原來的值,那麼我們應該想辦法在記憶體中例項化一個新的物件。在 Python 中,有幾個函式支援這種方法:dict()
、copy()
和 deepcopy()
。
dict()
函式例項化一個新的字典物件。如果你把一個現有的字典包在這個函式週圍,就會建立一個新的物件例項。
對於這個方法,我們將使用字典 food
中的同一個例子。
meal = dict(food)
另一種通過值傳遞的方法是使用 copy()
命令,它做的事情和 dict()
一樣:在記憶體中例項化一個新物件。不同的是 copy()
是集合物件的內建函式,包括字典。
meal = food.copy()
對於這兩種情況,我們修改 Fruit
值,替換 Vegetable
鍵。
meal['Fruit'] = 'Apple'
meal['Greens'] = meal.pop('Vegetable')
print(food)
print(meal)
輸出:
{'Fruit': 'Orange', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'} # food (original)
{'Fruit': 'Apple', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Greens': 'Lettuce'} # meal (copy)
通過使用 dict()
或 copy()
例項化一個新的物件 meal
,我們避免了在 meal
更新時引用原物件並更新其值。
Python 字典的淺層複製
dict()
和 copy()
的問題是它們只對正在使用的物件進行淺層複製;如果你的字典有複雜的巢狀結構,這將是一個問題。
淺層複製只會複製它看到的記憶體中的第一層,因為巢狀物件會佔用新的空間。
讓我們把原來的物件改成一個巢狀的字典。
info = { "Numbers": [1, 2, 3],
"Resident Name": "Sherlock",
"Address": {"Street": "Baker",
"Number": "221B",
"City": "Miami"
}
}
讓我們使用 copy()
和 dict()
宣告一個新的物件 info2
,從 info
複製並改變巢狀字典中的一些值。
info2 = info.copy() # or dict(info)
info2['Numbers'][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
輸出:
{'Numbers': [1, 4, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
原始版本和複製版本都更新了 Numbers
和 Address.City
的新值。Resident Name
值只更新了 info2
塊,因為我們只對物件進行了淺層複製。
在 Python 中使用 copy
模組進行深度複製
深度複製基本上解決了淺層複製的問題。在複製一個物件時,它會檢查是否有巢狀物件,並在記憶體中遞迴地建立新的物件。
在 Python 中,我們可以通過模組 copy
來實現深度複製,它包含了淺層和深層複製操作和實用程式。
import copy
我們將使用模組中的 deepcopy()
函式來深度複製我們字典中的巢狀物件。我們將使用上面同樣的例子 info
塊。
info2 = copy.deepcopy(info)
info2['Numbers'][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
輸出:
{'Numbers': [1, 2, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Miami'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
現在,原始字典 info
保持不變,即使在 info2
中進行了多次修改,包括巢狀物件。
綜上所述,在 Python 中複製字典的方法有很多,但輸出的結果不會都一樣。直接用 =
賦值一個字典,會通過引用傳遞,指向原來的物件。
像 dict()
和 copy()
這樣的淺層複製函式只能解決非巢狀字典的問題。
考慮到巢狀字典,複製字典的最好方法是使用 copy
模組提供的 deepcopy()
函式。
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn