2015-03-31 179 views
0
ddic = {'a': 10,'b': 23,'c': [0, 1, 2]} 
n2 = ddic['c'] 
n2[-2] = 1000. 

ddic 
{'a': 10, 'b': 23, 'c': [0, 1000.0, 2]} 

爲什麼更改n2指向的列表,還會更改dict ddic列表,該列表包含在ddic定義的哈希表中?作爲字典中的值列表Python

它看起來像是當你定義一個字典時,鍵值對在全局名字空間中彈出並且不包含在哈希表結構定義的名字空間中。

有人知道這個的詳細原因嗎?

+0

如果您認爲它解決了您的問題,請[接受](http://meta.stackexchange.com/questions/5234)答案。它將使整個社區認識到正確的解決方案。這可以通過點擊答案旁邊的綠色複選標記來完成。請參閱此[圖片](http://i.stack.imgur.com/uqJeW.png)以供參考。乾杯。 – 2015-12-09 07:44:10

回答

2

很少prenotes

  • 字典鍵是不可變的,而值是可變的。
  • 當您使用=,新的變量只是引用舊名單

在關鍵c的值是一個列表。這是指在那個地方的關鍵。在複製到變量時,參考被傳遞。這可以通過使用id來確認。

>>> id(ddic['c']) 
140726603094424 
>>> id(n2) 
140726603094424 

正如您所看到的,這兩個變量都指向內存中的相同元素。因此,你所做的任何改變都會反映到原來的改變中。

要讓列表的淺副本,你可以使用[:]as mentioned by Blckknght

>>> n2 = ddic['c'][:] 

在python3,你可以使用(由Padraic提到的)

>>> n2 = ddic['c'].copy() 

使用copy模塊,可以防止這發生在

>>> import copy 
>>> n2 = copy.copy(ddic['c']) 
>>> id(ddic['c']) 
140726603094424 
>>> id(n2) 
140726603177640 

參考

還要注意的是,由Kasra在評論中提到的,類型的字典沒有爲他們獨立的空間,因爲它們的數據結構。你可以在this找到參考文檔

+0

你也可以注意到'哈希表'沒有爲他們自己的空白,因爲他們是數據結構! http://svn.python.org/view/python/trunk/Objects/dictobject.c?view=markup – Kasramvd 2015-03-31 18:58:18

+1

你的意思是'字典鍵是不可變的'? – 2015-03-31 18:59:53

+0

@RussellBorogove糟糕! Twas是一個糟糕的錯字 – 2015-03-31 19:01:18

1

這是Python初學者陷入的一個經典陷阱。 Python中的某些對象是不可變的(例如整數,字符串,元組)。某些對象是可變的(例如:列表,字典,實例)。

如果修改可變對象,則所有引用該對象的其他對象都將看到修改後的值。

,如果你不希望修改DDIC [「C」]你必須做出一個副本

n2 = list(ddic['c']) 
n2[-2] = 1000 

ddic 
{'a': 10,'b': 23,'c': [0, 1, 2]} 
1

n2是在你的字典列表對象的引用。當你訪問ddic['c']時,你指向的是字典中的同一個列表對象,而不是它的副本。

+0

嚴格來說,該列表既不是「在」字典中,也不是「在」n2中。字典和變量n2都有一個對它的引用。 – 2015-03-31 19:05:36

相關問題