<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 準備知識 一些基本的定義: * 在Python中對象的賦值其實就是對象的引用。當創建一個對象,把它賦值給另一個變量的時候,python并沒有拷貝這個對象,只是拷貝了這個對象的引用而已。 * 淺拷貝:拷貝了最外圍的對象本身,內部的元素都只是拷貝了一個引用而已。也就是,把對象復制一遍,但是該對象中引用的其他對象我不復制 * 深拷貝:外圍和內部元素都進行了拷貝對象本身,而不是引用。也就是,把對象復制一遍,并且該對象中引用的其他對象也復制。 幾個術語的解釋 * 變量:是一個系統表的元素,擁有指向對象的連接空間 * 對象:被分配的一塊內存,存儲其所代表的值 * 引用:是自動形成的從變量到對象的指針 * 注意:類型(int類型,long類型(python3已去除long類型,只剩下int類型的數據))屬于對象,不是變量 * 不可變對象:一旦創建就不可修改的對象,包括字符串、元組、數字 * 可變對象:可以修改的對象,包括列表、字典。 深淺拷貝的作用 * 減少內存的使用? * 以后在做數據的清洗、修改或者入庫的時候,對原數據進行復制一份,以防數據修改之后,找不到原數據。 對于不可變對象的深淺拷貝   不可變對象類型(這個不可變對象類型里面不能包含可變對象類型,如元祖里面包含列表就不滿足這個條件),沒有被拷貝的說法,即便是用深拷貝,查看id的話也是一樣的,如果對其重新賦值,也只是新創建一個對象,替換掉舊的而已。一句話就是,不可變類型,不管是深拷貝還是淺拷貝,地址值和拷貝后的值都是一樣的。 ## 數字、字符串等不可變數據類型 ### 賦值 舉個栗子: ~~~ n1 = 123123 n2 = n1 print(n1,n2) print(id(n1)) print(id(n2)) 輸出結果: 123123 123123 1607915318992 1607915318992 ~~~   在以上代碼塊當中,a2與a1所賦的值是一樣的,都是數字123123。因為python有一個重用機制,對于同一個數字,python并不會開辟一塊新的內存空間,而是維護同一塊內存地址,只是將該數字對應的內存地址的引用賦值給變量a1和a2。所以根據輸出結果,a1和a2其實對應的是同一塊內存地址,只是兩個不同的引用罷了。同樣的,對于a2 = a1,其實效果等同于“a1 = 123123; a2 = 123123”,它也就是將a1指向123123的引用賦值給a2。字符串跟數字的原理雷同,如果把123123改成“abcabc”也是一樣的。 **結論:對于通過用 = 號賦值,數字和字符串在內存當中用的都是同一塊地址。** ### 淺拷貝 同樣的栗子: ~~~ import copy # 使用淺拷貝需要導入copy模塊 n1 = 123123 n3 = copy.copy(n1) # 使用copy模塊里的copy()函數就是淺拷貝了 print(n1,n3) print(id(n1)) print(id(n3)) 輸出結果: 123123 123123 2735567515344 2735567515344 ~~~   通過使用copy模塊里的copy()函數來進行淺拷貝,把a1拷貝一份賦值給a3,查看輸出結果發現,a1和a3的內存地址還是一樣。 **結論:對于淺拷貝,數字和字符串在內存當中用的也是同一塊地址。** ### 深拷貝 再來一個栗子: ~~~ import copy n1 = 123123 n4 = copy.deepcopy(n1) # 深拷貝是用copy模塊里的deepcopy()函數 print(n1,n4) print(id(n1)) print(id(n4)) 輸出結果: 123123 123123 2545114525392 2545114525392 ~~~ **結論:綜上所述,對于數字和字符串的賦值、淺拷貝、深拷貝在內存當中用的都是同一塊地址。** 原理圖: ![](https://img.kancloud.cn/9d/33/9d331f5fd5d634b8e30e2371f4124982_543x414.png) ## 字典、列表等可變數據類型 ### 賦值 再舉個栗子 ~~~ n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 678]} n2 = n1 # 賦值 print(n1,n2) print(id(n1)) print(id(n2)) n1['k1'] = 'c' n1['k3'][0] = 'd' print(n1,n2) print(id(n1)) print(id(n2)) 輸出結果: ~~~ {'k1': 'wu', 'k2': 123, 'k3': \['alex', 678\]} {'k1': 'wu', 'k2': 123, 'k3': \['alex', 678\]} 1867471875528 1867471875528 {'k1': 'c', 'k2': 123, 'k3': \['d', 678\]} {'k1': 'c', 'k2': 123, 'k3': \['d', 678\]} 1867471875528 1867471875528 ?  我們的栗子當中用了一個字典n1,字典里面嵌套了一個列表,當我們把n1賦值給n2時,內存地址并沒有發生變化,因為其實它也是只是把n1的引用拿過來賦值給n2而已(我們用了一個字典來舉例,其他類型也是一樣的)。正因為如此,當我們修改字典里面的數據時,n1和n2都會發生改變。 ![](https://img.kancloud.cn/47/2e/472e5d849495c229eecaf03519656694_493x363.png) **  結論:對于賦值,字典、列表等其他類型用的內存地址不會變化。** ### 淺拷貝 栗子走起 ~~~ import copy n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 678]} n3 = copy.copy(n1) # 淺拷貝 print(n1,n3) print("第一層字典的內存地址:") print(id(n1)) print(id(n3)) print("第二層嵌套的列表的內存地址:") print(id(n1["k3"])) print(id(n3["k3"])) n1['k1'] = 'tom' n1['k3'][0] = 'jack' print('***************') print(n1,n3) 輸出結果: {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} 第一層字典的內存地址: 1506727325128 1506727325200 第二層嵌套的列表的內存地址: 1506758960840 1506758960840 *************** {'k1': 'tom', 'k2': 123, 'k3': ['jack', 678]} {'k1': 'wu', 'k2': 123, 'k3': ['jack', 678]} ~~~   通過以上結果可以看出,進行淺拷貝時,我們的字典第一層n1和n3指向的內存地址已經改變了,但是對于第二層里的列表并沒有拷貝,它的內存地址還是一樣的。原理如下圖:   ![](https://img.kancloud.cn/7d/d8/7dd8138c38ad4df8b494dd1f668f9300_431x375.png) **?  結論:所以對于淺拷貝,字典、列表等類型,它們只拷貝第一層地址。** ### 深拷貝 栗子: ~~~ import copy n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 678]} n4 = copy.deepcopy(n1) # 深拷貝 print("第一層字典的內存地址:") print(id(n1)) print(id(n4)) print("第二層嵌套的列表的內存地址:") print(id(n1["k3"])) print(id(n4["k3"])) n1['k1'] = 'tom' n1['k3'][0] = 'jack' print(n1,n4) 輸出結果: {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} 第一層字典的內存地址: 1853270748616 1853271588800 第二層嵌套的列表的內存地址: 1853273351880 1853273350600 *************** {'k1': 'tom', 'k2': 123, 'k3': ['jack', 678]} {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} ~~~   通過以上結果發現,進行深拷貝時,字典里面的第一層和里面嵌套的地址都已經變了。對于深拷貝,它會拷貝多層,將第二層的列表也拷貝一份,如果還有第三層嵌套,那么第三層的也會拷貝,但是對于里面的最小元素,比如數字和字符串,這里就是“wu”,123,“alex”,678之類的,按照python的機制,它們會共同指向同一個位置,它的內存地址是不會變的。原理如下圖: ![](https://img.kancloud.cn/fe/4f/fe4f5e4f4739d71587d946cbd4786b09_382x331.png) ?**結論:對于深拷貝,字典、列表等類型,它里面嵌套多少層,就會拷貝多少層出來,但是最底層的數字和字符串地址不變,是一樣的。** **PS:** 對于元祖來說,如果他里面的元素都是不可變類型的元素,那么不論是賦值,淺拷貝還是深拷貝,他們的id都是一樣的(不僅整個元祖的id是一樣的,里面每一個元素的id都是一樣的)。但是如果元祖里面的元素有可變元素,如列表字典等,那么對于賦值和淺拷貝來說,id仍然還是一樣的(不僅整個元祖的id是一樣的,里面每一個元素的id都是一樣的);對于深拷貝來說,元祖的id和列表字典的id是不一樣的,但是對于最底層的數字,字符串地址還是一樣的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看