在作數據處理的時候, 碰到一個奇怪的現象.數組
for tuple in list.most_common(): dict['name'] = tuple[0] dict['value'] = tuple[1] d1.append(dict) print(d1)
[{'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}, {'name': '大興', 'value': 32}]
發現d1這個列表裏的每一個元素都是同樣的. 檢查循環裏的tuple 和 dict 一切正常.
循環裏的d1 就不太正常...app
for tuple in list.most_common(): dict['name'] = tuple[0] dict['value'] = tuple[1] d1.append(dict) print(d1)
[{'name': '朝陽', 'value': 102}]
[{'name': '海淀', 'value': 65}, {'name': '海淀', 'value': 65}]
[{'name': '昌平', 'value': 53}, {'name': '昌平', 'value': 53}, {'name': '昌平', 'value': 53}]
[{'name': '豐臺', 'value': 53}, {'name': '豐臺', 'value': 53}, {'name': '豐臺', 'value': 53}, {'name': '豐臺', 'value': 53}]
[{'name': '西城', 'value': 48}, {'name': '西城', 'value': 48}, {'name': '西城', 'value': 48}, {'name': '西城', 'value': 48}, {'name': '西城', 'value': 48}]
部分數據是這樣的. 發生了append的操做, 但列表裏全部元素的值都同樣. 爲何會這樣?編碼
幾個小時後, 想到了一種可能性. 在append操做的時候, 傳入的是一個引用, 致使後期dict變化, 前面元素的值也跟着變化. 解決方法是傳入一個dict的copy, 傳一個值, 而不是引用. code
修改後的代碼:開發
for tuple in list.most_common(): dict['name'] = tuple[0] dict['value'] = tuple[1] d = copy.copy(dict) d1.append(d) print(d1)
[{'name': '朝陽', 'value': 102}, {'name': '海淀', 'value': 65}, {'name': '豐臺', 'value': 53}, {'name': '昌平', 'value': 53}, {'name': '西城', 'value': 48}, {'name': '通州', 'value': 36}, {'name': '大興', 'value': 32}, {'name': '東城', 'value': 22}, {'name': '順義', 'value': 18}, {'name': '石景山', 'value': 16}, {'name': 'NULL', 'value': 11}, {'name': '房山', 'value': 7}, {'name': '門頭溝', 'value': 6}, {'name': '燕郊', 'value': 5}, {'name': '亦莊開發區', 'value': 3}]
ok, 確實是假想的那樣, 傳引用產生的問題, 加上一個拷貝語句就能夠了. 但是以前也作過很多的利用append來構造字典數組的案例, 從沒碰到過問題, 也沒有添加過拷貝. 仔細觀察之下, 發現個人 dict= {} 聲明是放在for循環外的. 那這應該就是問題所在了.for循環
再次修改後的代碼:循環
for tuple in list.most_common(): # 把dict的定義放入 for 循環內 dict = {} dict['name'] = tuple[0] dict['value'] = tuple[1] # d = copy.copy(dict) d1.append(dict) print(d1)
總結一下, 因爲疏忽把dict= {}放在for循環外, 在append的時候, 一直添加的是同一個dict的引用, dict 內的值變化, 引發了列表內全部元素的變化.
在最後的修改裏, 每一次循環, 都會新建一個空字典, 每次循環 dict 都是一個獨立的值. 正確的作法也應該是這樣的. 引用
PS: 嘗試了一下, Js的arr.push(obj) 也有一樣的問題, 固然有良好編碼習慣的人是不會碰到這種問題的.方法