站長資訊網
        最全最豐富的資訊網站

        Python 中變量賦值傳遞時的引用和拷貝

        曾經看到這樣一個問題,一個字典中的元素是列表,將這個列表元素賦值給一個變量,然后修改這個列表中元素的值,結果發現,字典中那個列表也同樣修改了。那個問題如下:

        dict = {'a':[1,2,3,4,5],'b':2}  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的值并不受影響。

        >>> dict = {'a':[1,2,3,4,5],'b':2}  >>> x = dict['b']  >>> x  2  >>> x=x+3  >>> x  5  >>> dict  {'a': [1, 2, 3, 4, 5], 'b': 2}  >>>

        那么問題來了,變量賦值傳遞時什么情況下是傳值(拷貝),什么情況下是傳址(引用)呢?

        1、直接拷貝

        當我們不知道是引用還是拷貝的情況下,可以顯式的拷貝。比如字典對象本身都具有拷貝的方法:

        x=dict.copy()

        沒有拷貝方法的對象,也是可以拷貝的。這兒我們引入一個深拷貝的概念,深拷貝——即python的copy模塊提供的一個deepcopy方法。深拷貝會完全復制原變量相關的所有數據,在內存中生成一套完全一樣的內容,在這個過程中我們對這兩個變量中的一個進行任意修改都不會影響其他變量。還是上面的代碼,如果改成如下:

        import copy  dict = {'a':[1,2,3,4,5],'b':2}  x = copy.deepcopy(dict['a'])  for i in range(5):      x[i] = 0  print(dict['a'])

        運行結果dict值不受影響。

        除了深拷貝,copy模塊還提供一個copy方法,稱其為淺拷貝,對于簡單的對象,深淺拷貝都是一樣的,上面的詞典對象的copy方法就是淺拷貝。

        >>> dict  {'a': [8, 2, 3, 4, 5], 'b': 4}  >>> dd=copy.copy(dict)  >>> dd  {'a': [8, 2, 3, 4, 5], 'b': 4}  >>> dd['a'][0]=7  >>> dd  {'a': [7, 2, 3, 4, 5], 'b': 4}  >>> dict  {'a': [7, 2, 3, 4, 5], 'b': 4}  >>> ee=dict.copy()  >>> ee  {'a': [7, 2, 3, 4, 5], 'b': 4}  >>> ee['a'][0]=9  >>> ee  {'a': [9, 2, 3, 4, 5], 'b': 4}  >>> dict  {'a': [9, 2, 3, 4, 5], 'b': 4}  >>> ee['b']=5  >>> ee  {'a': [9, 2, 3, 4, 5], 'b': 5}  >>> dict  {'a': [9, 2, 3, 4, 5], 'b': 4}  >>>

        淺拷貝時改變第一層次相互不受影響(上例中詞典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后,地址就變了。

        原文鏈接:https://blog.csdn.net/iamlaosong/article/details/77505510

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产精品无码国模私拍视频 | 久久精品国产清高在天天线| 久久99国产精品久久| 无码国模国产在线无码精品国产自在久国产 | 国产亚洲精品成人a v小说| 国产精品亚洲成在人线| 亚洲精品无码mv在线观看网站| 国产三级精品三级在线观看专1| 2021久久精品国产99国产精品| 亚洲精品高清无码视频| 乱人伦人妻精品一区二区| 国产AV国片精品一区二区| 精品国产综合成人亚洲区| 精品成在人线AV无码免费看| 香蕉依依精品视频在线播放 | 国产精品免费视频观看拍拍| 青青草精品视频| 国产精品福利一区二区久久| 久久精品无码午夜福利理论片 | 精品一区二区三区色花堂| 在线观看日韩精品| 久久777国产线看观看精品| 99久久精品毛片免费播放| 精品国偷自产在线| 国产午夜精品一区二区三区 | 99久久99久久精品免费看蜜桃 | 亚洲精品国产精品乱码不卡√| 亚洲一区二区精品视频| 亚洲av无码成人精品区在线播放| 久久午夜无码鲁丝片午夜精品 | 国产乱子伦精品免费视频| 国产精品美女免费视频观看| 亚洲精品高清视频| 亚洲人成亚洲精品| 2023国产精品自拍| 99精品久久久久久久婷婷| 99熟女精品视频一区二区三区 | 1区1区3区4区产品芒果精品| 91精品国产自产在线观看| 99热精品久久只有精品| 精品国产91久久久久久久a|