1. 程式人生 > >【Python】列表巢狀字典修改字典裡面的一個值卻把全部的值都修改了。

【Python】列表巢狀字典修改字典裡面的一個值卻把全部的值都修改了。

具體問題就是:當我往空列表裡面新增字典,需要修改其中的一個鍵的值的時候,出現把其他同類的值也修改了。

下面就是出現問題的程式碼:

aliens = []
new_alien = {"color": "green"}
#往字典裡新增5個字典
for num in range(5):
    aliens.append(new_alien)
print(aliens)
#修改第一個字典的顏色
aliens[0]["color"] = "blue"
print(aliens)

結果出現全部的值都修改了,如下

G:\python\python\pra\venv\Scripts\python.exe G:/python/python/pra/day02/列表巢狀字典修改問題5.py
[{'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
[{'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}]

至於為什麼出現這樣的問題,我在網上查了一點資料,我的理解就是把字典新增到列表裡面,其實它執行的把字典的地址給了列表,但是沒有真正地把內容給他,導致你在修改的時候,改變的是原來地址的物件,又由於列表裡的其他的元素指向的是同一個物件,所以出現了後面的值都修改的現象.

至於為什麼這樣說,先看一下它的地址:

aliens = []
new_alien = {"color": "green"}
# 列印一下原來的地址
print(id(new_alien))
#往字典裡新增5個字典
for num in range(5):
    aliens.append(new_alien)
print(aliens)
# 列印列表原來的地址
for alien in aliens:
    print(id(alien))
#修改第一個字典的顏色
aliens[0]["color"] = "blue"
print(aliens)
# 列印列表修改後的地址
for alien in aliens:
    print(id(alien))

結果就是下面的這個,可以看到這些地址的值都是一樣的.至於為什麼會出現這個問題?這個涉及到append()函式與淺拷貝與深拷貝的問題.可以參考一下python append()與深拷貝、淺拷貝.

1430100602312
[{'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
1430100602312
1430100602312
1430100602312
1430100602312
1430100602312
[{'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}, {'color': 'blue'}]
1430100602312
1430100602312
1430100602312
1430100602312
1430100602312

對於解決的辦法,我找到了兩個:

第一個:匯入copy模組使用深拷貝,再把字典新增到列表裡面

import copy
aliens = []
new_alien = {"color": "green"}
# 列印一下原來的地址
print(id(new_alien))
#往字典裡新增5個字典
for num in range(5):
    aliens.append(copy.deepcopy(new_alien))
print(aliens)
# 列印列表原來的地址
for alien in aliens:
    print(id(alien))
#修改第一個字典的顏色
aliens[0]["color"] = "blue"
print(aliens)
# 列印列表修改後的地址
for alien in aliens:
    print(id(alien))

結果如下,可以看到結果就如我們想象的一樣.並且每一個字典的id都不一樣.

G:\python\python\pra\venv\Scripts\python.exe G:/python/python/pra/day02/列表巢狀字典修改問題5.py
2801414139336
[{'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
2801443357032
2801443357464
2801445044944
2801443651232
2801443651448
[{'color': 'blue'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
2801443357032
2801443357464
2801445044944
2801443651232
2801443651448

第二種方法:將需要新增的字典放到for迴圈裡面.

aliens = []
#往字典裡新增5個字典
for num in range(5):
    new_alien = {"color": "green"}
    aliens.append(new_alien)
print(aliens)
# 列印列表原來的地址
for alien in aliens:
    print(id(alien))
#修改第一個字典的顏色
aliens[0]["color"] = "blue"
print(aliens)
# 列印列表修改後的地址
for alien in aliens:
    print(id(alien))

結果如下,每個字典的id都是不一樣的,結果也是我們想要的.

[{'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
2433848405448
2433848405520
2433848405880
2433878409360
2433848405808
[{'color': 'blue'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}, {'color': 'green'}]
2433848405448
2433848405520
2433848405880
2433878409360
2433848405808

好了,這問題暫時到這了,可以我說的有些不太嚴謹,有些地方可能有問題,如果有,希望大家可以指出了,本人也是剛學Python的,謝謝閱讀.