Python語法學習記錄(19):numpy中淺拷貝和list中淺拷貝的異同

相關鏈接另一篇bolg講述list中的淺拷貝問題
Python語法學習記錄(9):list淺拷貝問題解析

1、numpy中淺拷貝的產生與判斷方法

1.1 淺拷貝的產生

一般通過直接 = 賦值產生

1.2 通過兩種方式進行淺拷貝的判斷

1.2.1 查詢存儲路徑判斷淺拷貝

查看每一個的存儲編號,如果相同就是存在淺拷貝因爲指向相同的位置,變量名字只是用來索引到那個存儲位置,改變任何一個變量名下面的內容,都會讓那個存儲位置內容改變,導致其他存在淺拷貝關係的變量名下面的內容也發生改變。

1.2.2 通過is函數判斷是否一樣判斷淺拷貝

is函數原理和id原理近似

import numpy as np
a = np.arange(4)
b = a
c = a
d = b
# 查看每一個的存儲編號  
print(id(a))
print(id(b))
print(id(c))
print(id(d))
# 淺拷貝的現象  更改一個變量  相關淺拷貝變量都會改變
print(a)
a[0] = 11
print(a)
print(b)
print(c)
print(d)
# 通過is() 判斷淺拷貝
print(b is a)  
print(c is a) 
print(d is a)

2、規避淺拷貝的方法

通過copy的方法進行無淺拷貝的等價於複製的賦值

import numpy as np

a = np.arange(4)
print("a:",a)
b = a.copy()    # deep copy
print("b:",b)        # array([11, 22, 33,  3])
print(id(a))
print(id(b))
a[3] = 44
print(a)        # array([11, 22, 33, 44])
print(b)        # array([11, 22, 33,  3])

3、numpy中變量部分淺拷貝的問題

當將矩陣的部分內容進行賦值的時候也會產生淺拷貝,這個時候出現問題其實很難判斷

下面介紹一下部分淺拷貝的問題和判斷方法

a = np.array([1,2,3,4,5])
# 全變量的淺拷貝
b = a
print('a id',id(a))
print('b id',id(b))
print('a.shape',a.shape)
a[2] = 9
print('a ',a)
print('b ',b)
# 變量部分矩陣單元的淺拷貝
b = a[1:3]
print('a ',a)
print('b ',b)
print('b.shape ',b.shape)
b[0] = 100
print('a ',a)
print('b ',b)
print('a id',id(a))
print('a[0] id',id(a[0]))
print('a[1] id',id(a[1]))
print('a[2] id',id(a[2]))
print('a[3] id',id(a[3]))
print('a[4] id',id(a[4]))
print('a[0:3] id',id(a[0:3]))
print('a[1:3] id',id(a[1:3]))
print('a[2:3] id',id(a[2:3]))
print('b id',id(b))
print('b[0] id',id(b[0]))
print('b[1] id',id(b[1]))
a[2] =1000
print('a ',a)
print('b ',b)
print('a id',id(a))
print('a[0] id',id(a[0]))
print('a[1] id',id(a[1]))
print('a[2] id',id(a[2]))
print('a[3] id',id(a[3]))
print('a[4] id',id(a[4]))
print('a[1:3] id',id(a[1:3]))
print('b id',id(b))
print('b[0] id',id(b[0]))
print('b[1] id',id(b[1]))

a = np.ones((4,5))
# 全變量的淺拷貝
b = a
print('a id',id(a))
print('b id',id(b))
print('a.shape',a.shape)
a[1,3] = 9
print('a ',a)
print('b ',b)
# 變量部分矩陣單元的淺拷貝
b = a[1:3,1:4]
print('a ',a)
print('b ',b)
print('b.shape ',b.shape)
b[0,1] = 100
print('a ',a)
print('b ',b)
print('a id',id(a))
print('a[0] id',id(a[0])) # 結果和a[1],a[2],a[3]一樣
print('a[0:3] id',id(a[0:3])) # 結果和a[1:3],a[2:3]一樣
print('a[0:3,1] id',id(a[0:3,1])) # 結果和a[1:3],a[2:3]一樣
print('a[1,0:3] id',id(a[1,0:3])) # 結果和a[1:3],a[2:3]一樣
print('a[0,0] id',id(a[0,0]))
print('a[0,1] id',id(a[0,1])) 
print('a[0,2] id',id(a[0,2])) 
print('a[1,0] id',id(a[1,0]))
print('a[1,1] id',id(a[1,1])) 
print('a[1,2] id',id(a[1,2])) 
print('b id',id(b))
print('b[0] id',id(b[0]))
print('b[1] id',id(b[1]))
print('b[0,0] id',id(b[0,0]))

4、numpy切片淺拷貝和list切片淺拷貝中的區別

主要是在部分淺拷貝或者切片淺拷貝的時候保存機制不一樣

import numpy as np
import sys

a = [[1,2,3,4],[5,6,7,8]]
b = a[0]
print('a[0] id 與 b id 是一樣的')
print('a id',id(a))
print('a[0] id',id(a[0]))
print('b id',id(b))

print('淺拷貝中元素賦值,相關變量也一起改變')
a[0][0] = 9
print('a ',a)
print('b ',b)
print('a id',id(a))
print('a[0] id',id(a[0]))
print('b id',id(b))

a = [[1,2,3,4],[5,6,7,8]]
b = a[0]

print('淺拷貝整個變量重新賦值,相關變量指向原來的位置,所以不變,淺拷貝破壞')
print('a[0] id',id(a[0]))
print('b id',id(b))
a[0] = 100
print('a ',a)
print('b ',b)
print('a id',id(a))
print('a[0] id',id(a[0]))
print('b id',id(b))

print('與numpy中不同的這裏對於切片或者部分的淺拷貝在後續賦值過程中會被破壞')
print('切片淺拷貝')
print('從id上看切片賦值淺拷貝是存在的,但是從is上看,改變賦值狀態另一個卻不變化了')
a = [1,2,3,4,5,6,7,8]
b = a[1:4]

print('a[2] id:', id(a[2]))
print('b[1] id:', id(b[1]))
print('     is',b is a[1:4])
print('     is',b[1] is a[2])
print('a:', a)
print('b:', b)

a[2] = 100
# b[1] = 100
print('=================')

print('a[2] id:', id(a[2]))
print('b[1] id:', id(b[1]))
print('     is',b is a[1:4])
print('     is',b[1] is a[2])
print('a:', a)
print('b:', b)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章