欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          Python 中變量賦值傳遞時(shí)的引用和拷貝

          曾經(jīng)看到這樣一個(gè)問題,一個(gè)字典中的元素是列表,將這個(gè)列表元素賦值給一個(gè)變量,然后修改這個(gè)列表中元素的值,結(jié)果發(fā)現(xiàn),字典中那個(gè)列表也同樣修改了。那個(gè)問題如下:

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

          程序運(yùn)行結(jié)果如下: [0, 0, 0, 0, 0]

          這兒涉及到Python賦值到底是引用還是拷貝一份的問題,即賦值時(shí)是傳值還是傳址。上面問題是將”a”的值賦給了x出現(xiàn)了上述情況,如果是將”b”的值賦給了x,當(dāng)我們修改x的值時(shí),字典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}  >>>

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

          1、直接拷貝

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

          x=dict.copy()

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

          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'])

          運(yùn)行結(jié)果dict值不受影響。

          除了深拷貝,copy模塊還提供一個(gè)copy方法,稱其為淺拷貝,對(duì)于簡單的對(duì)象,深淺拷貝都是一樣的,上面的詞典對(duì)象的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}  >>>

          淺拷貝時(shí)改變第一層次相互不受影響(上例中詞典b值的修改),第二層次(上例中詞典a的列表值修改)就相互影響了,改一個(gè),其他跟著變??纯磇d吧:

          >>> id(dict)  20109472  >>> id(dd)  20244496  >>> id(ee)  20495072  >>> id(dd['a'])  20272112  >>> id(ee['a'])  20272112  >>> id(dict['a'])  20272112  >>>

          可見詞典各個(gè)拷貝的id是不同的,但詞典a值的id是相同的。如果我們需要真正意義的拷貝,就用深拷貝吧。

          2、傳遞規(guī)則

          Python 賦值過程中不明確區(qū)分拷貝和引用,一般對(duì)靜態(tài)變量的傳遞為拷貝,對(duì)動(dòng)態(tài)變量的傳遞為引用。(注,對(duì)靜態(tài)變量首次傳遞時(shí)也是引用,當(dāng)需要修改靜態(tài)變量時(shí),因?yàn)殪o態(tài)變量不能改變,所以需要生成一個(gè)新的空間存儲(chǔ)數(shù)據(jù))。

          • 字符串,數(shù)值,元組均為靜態(tài)變量
          • 列表,字典為動(dòng)態(tài)變量。

          變量有時(shí)比較復(fù)雜,存在組合現(xiàn)象,比如字典中包含列表,列表中包含字典,但賦值時(shí),總是屬于某個(gè)類型。如果實(shí)在不清楚狀況,可以試驗(yàn)一下,用id()這個(gè)函數(shù)看看,如果是引用,兩個(gè)變量指向的地址是相同的。例如:

          >>> 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)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)