iamlaosong文
曾經看到這樣乙個問題,乙個字典中的元素是列表,將這個列表元素賦值給乙個變數,然後修改這個列表中元素的值,結果發現,字典中那個列表也同樣修改了。
那個問題如下:
dict =
x = dict['a']
for i in range(5):
x[i] = 0
print(dict['a'])
程式執行結果如下:
[0, 0, 0, 0, 0]
這兒涉及到python賦值到底是引用還是拷貝乙份的問題,即賦值時是傳值還是傳址。上面問題是將「a」的值賦給了x出現了上述情況,如果是將「b」的值賦給了x,當我們修改x的值時,字典dict的值並不受影響。
>>www.cppcns.com> dict =
>>> x = dict['b']
>>> x
2 >>> x=x+3
>>> x
5 >>> dict
>>>
那麼問題來了,變數賦值傳遞時什麼情況下是傳值(拷貝),什麼情況下是傳址(引用)呢?
1、直接拷貝
當我們不知道是引用還是拷貝的情況程式設計客棧下,可以顯式的拷貝。比如字典物件本身都具有拷貝的方法:
x=dict.copy()
沒有拷貝方法的物件,也是可以拷貝的。這兒我們引入乙個深拷貝的概念,深拷貝——即python的copy模組提供的乙個deepcopy方法。深拷貝會完全複製原變數相關的所有資料,在記憶體中生成一套完全一樣的內容,在這個過程中我們對這兩個變數中的乙個進行任意修改都不會影響其他變數。還是上面的**,如果改成如下:
import copy
dict =
x = copy.deepcopy(dict['a'])
for i in range(5):
x[i] = 0
print(dict['a'])
執行結果dict值不受影響。
除了深拷貝,copy模組還提供乙個copy方法,稱其為淺拷貝,對於簡單的物件,深淺拷貝都是一樣的,上面的詞典物件的copy方法就是淺拷貝。
>>> dict
>>> dd=copy.copy(dict)
>>> dd
>>> dd['a'][0]=7
>>> dd
>>> dict
>>> ee=dict.copy()
>>> ee
>>> ee['a'][0]=9
>>> ee
>>> dict
>>> ee['b']=5
>>> ee
>>> dict
>>>
淺拷貝時改變第一層次相互不受影響(上例中詞典b值的修改),第二層次(上例中詞典a的列表值修改)就相互影響了,改乙個,其他跟著變。看看id吧:
>>> id(dict)
20109472
>>> id(dd)
20244496
>>> id(ee)
20495072
>>> id(dd['a'])
20272112
>>> id(ee['a'])
20272112
>>> id(dict['a'])
20272112
>>>
可見詞典各個拷貝的id是不同的,但詞典a值的id是相同的。如果我們需要真正意義的拷貝,就用深拷貝吧。
2、傳遞規則
python賦值過程中不明確區分拷貝和引用,一般對靜態變數的傳遞為拷貝,對動態變數的傳遞為引用。(注,對靜態變數首次傳遞時也是引用,當需要修改靜態變數時,因為靜態變數不能改變,所以需要生成乙個新的空間儲存資料)。
字串,數值,元組均為靜態變數
列表,字典為動態變數。
變數有時比較複雜,存在組合現象,比如字典中包含列表,列表中包含字典,但賦值時,總是屬於某個型別。如果實在不清楚狀況,可以試驗一下,用id()這個函式看看,如果是引用,兩個變數指向的位址是相同的。例如:
>>> a=6
>>> id(a)
10413476
>>> b=a
>>> id(b)
10413476
>>> b=8
>>> id(b)
10413452
>>>
修改變數b之前,a和b指向的位址是相同的,修改b後,位址就變了。
本文標題: python中實現變數賦值傳遞時的引用和拷貝方法
本文位址: /jiaoben/python/226624.html
Python中變數傳遞時的引用和賦值
python中不明確區分賦值和應用,一般對靜態變數的傳遞為賦值,對動態變數的傳遞為引用。注,對靜態變數首次傳遞時也是應用,當需要修改靜態變數時,因為靜態變數不能改變,所以需要生成乙個新的空間儲存資料 個人覺得分清楚規則即可比較容易的區別。字串,整數,元組均為靜態變數 列表,字典為動態變數。以下示例在...
python變數傳遞 python變數傳遞
python變數傳遞 數值 num 1 123 num 2 num 1 改變num 2值前 print num 1 num 2 format num 1,num 2 num 2 0 改變num 2值後 print num 1 num 2 format num 1,num 2 輸出num 1 123,...
python傳遞變數 python變數傳遞
python變數傳遞 數值 num 1 123 num 2 num 1 改變num 2值前 print num 1 num 2 format num 1,num 2 num 2 0 改變num 2值後 print num 1 num 2 format num 1,num 2 輸出num 1 123,...