python 多層字典遇到的問題
1.問題
朋友有一個小測試,多層字典,想在最外層字典上改變內層字典的值,發現結果與預期差別很多,在外層字典中給內層字典的key賦值時,內層字典發生了改變,從而外層隨著發生改變。
具體代碼如下:
df = pd.DataFrame(all_list, columns=[col1, col2, num])
df的形式如下:
這裡想要把 col1和col2轉化成相關矩陣的模式,對應的num保留,其餘為0
all_word = list(set(list(df.col1.unique()) + list(df.col2.unique())))
dict_1d = {} # 定義一個字典
for item in all_word:
dict_1d[item] = 0.0
dict_2d = {} # 定義新的字典用於儲存改變後的值
# 將原字典的里數據放入新的字典中
for item in all_word:
dict_2d[item] = dict_1d
df[num] = list(df.num.astype(np.int32).values)
count = 0
dict = dict_2d
for index, row in df.iterrows():
# print row
# dict [row[0]][row[1]] = float(row[2]) / df.num.sum()
dict [row[0]][row[1]] = float(row[2])
dict [row[1]][row[0]] = float(row[2])
結果:
dict 值:只截取一個子字典的值。
大會學術交流: {三元乙丙橡膠: 2,
中國移動: 2,
產業投資: 2, 產品批號: 2, 公共體育: 0.0, 興趣: 4, 內化: 0.0, 寫作質量: 2, 農業生產形勢: 3, 副部長: 0.0, 化學推進: 2,發展水平: 0.0,
國際足聯: 0.0, 大會學術交流: 0.0, 委託檢驗: 2, 子行業: 0.0, 學生因素: 0.0, 孩子: 0.0, 宗旨理念: 2, 技術團隊: 2, 控制能力: 0.0,推力器: 0.0,
教師因素: 4, 早期閱讀: 3, 杜甫詩歌: 2, 杭州市區: 0.0, 檢索關鍵詞: 0.0, 涉農節目: 0.0, 豬肉產量: 0.0, 班級管理: 2, 生產線項目: 0.0,生平事迹: 0.0,
科學技術協會: 2, 經營規模: 2, 計量認證: 0.0, 認同: 2, 足球協會: 3, 閱讀問題: 0.0, 零部件供應商: 3, 零部件質量: 0.0},按照預期來說,
這個子字典的值 在 科學技術協會: 處的值為2,其餘均為0才對,但明顯不是。
看一下:dict_1d,
{三元乙丙橡膠: 2.0,
中國移動: 2.0, 產業投資: 2.0, 產品批號: 2.0, 公共體育: 4.0, 興趣: 4.0, 內化: 2.0, 寫作質量: 2.0,農業生產形勢: 3.0,
副部長: 2.0,dict_2d
大會學術交流: {三元乙丙橡膠: 2.0,
中國移動: 2.0, 產業投資: 2.0, 產品批號: 2.0, 公共體育: 4.0, 興趣: 4.0, 內化: 2.0,寫作質量: 2.0,
......
這裡我們看下之前定義的dict_1d,發現他的值已經不是全零了,同樣的dict_2d的值也不是全0的了,在 dict[row[0]][row[1]] = float(row[2]) 賦值的時候 同時改變了dict_1d和dict_2d,因此在迭代中,原始的值已經發生了改變,因此得不到預期的結果。
可以發現字典的重新賦值會導致調用他的外層字典的值同步改變。和list相似:
a=[1,2,3,4]
b=a
b[1]=100
a
>>[1,100,3,4]
ps:即便是利用深度拷貝:
count = 0
from copy import deepcopy
dict = deepcopy(dict_2d)
for index, row in df.iterrows():
# print row
# dict_2d[row[0]][row[1]] = float(row[2]) / df.num.sum()
dict[row[0]][row[1]] = float(row[2])
dict[row[1]][row[0]] = float(row[2])
dict
大會學術交流: {三元乙丙橡膠: 2.0,
中國移動: 2.0, 產業投資: 2.0, 產品批號: 2.0, 公共體育: 4.0, 興趣: 4.0, 內化: 2.0, 寫作質量: 2.0, 農業生產形勢: 3.0,結果也還是同之前一樣,發生了改變。
之後用多層字典就要注意了。。。
2.解決方法:
這裡的解決方式是,先將多層字典變成dataframe,而後在dataframe中改變對應的值,結果就能夠符合預期、
### 在 dataframe 中 能夠直接修改值
new_df = pd.DataFrame(dict_2d)
for index, row in df.iterrows():
new_df.loc[row[0],row[1]]= float(row[2])
new_df.loc[row[1],row[0]]= float(row[2])
#print dict_2d[row[0]][row[1]]
推薦閱讀:
※白帽和黑帽seo的區別
※新手——010純手工編輯打造PE文件
※蘋果市值離萬億一步之遙,庫克時代最了不起的成就!
※0day漏洞組合拳:詳細分析一款惡意PDF樣本
※對接Wi-Fi,Li-Fi的時代即將到來!