[英]Is there aliasing in a 2-D array in Python?
我知道列表別名是Python中的問題,但我想不出辦法。
def zeros(A):
new_mat = A
for i in range(len(A)):
for j in range(len(A[i])):
if A[i][j]==0:
for b in range(len(A)):
new_mat[b][j] = 0
else:
new_mat[i][j] = A[i][j]
return A
即使我根本不更改A的值,當我返回A時,它仍然被修改:
>>> Matrix = [[1,2,3],[5,0,78],[7,3,45]]
>>> zeros(Matrix)
[[1, 0, 3], [5, 0, 78], [7, 0, 45]]
這個列表是別名嗎? 如果是這樣,如何在不發生混疊的情況下修改2D數組的元素? 謝謝,謝謝<3。
new_mat = A
不會創建新矩陣。 您僅給對象又賦予了新名稱A
如果是數字列表,則可能要使用copy.deepcopy創建完整副本;如果是numpy數組,則可以使用copy方法。
new_mat = A[:]
這將創建列表的副本,而不僅僅是引用它。 試試看。
[:]
僅指定一個從頭到尾的切片。 例如,您可以有[1:]
,它從元素1到末尾,或者[1:4]
,它是元素1至4。 查看與此相關的列表切片。
這可能會幫助其他人。 只是這樣做。
import copy
def zeros(A):
new_mat = copy.deepcopy(A)
快速說明
如果您希望A成為原始矩陣,則您的函數應如下所示。 只需使用np.copy()
函數
def zeros(A):
new_mat = np.copy(A) #JUST COPY IT WITH np.copy() function
for i in range(len(A)):
for j in range(len(A[i])):
if A[i][j]==0:
for b in range(len(A)):
new_mat[b][j] = 0
else:
new_mat[i][j] = A[i][j]
return A
徹底的解釋
假設我們不希望numpy ndarray a
具有別名。 例如,我們要防止a
在獲取(例如)它的一個切片時將其任何值更改,我們將此切片分配給b
,然后修改b的一個元素。 我們要避免這種情況:
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = a[0]
b[2] = 50
a
Out[]:
array([[ 1, 2, 50],
[ 4, 5, 6],
[ 7, 8, 9]])
現在,您可能認為將numpy-ndarray對象視為列表對象可以解決我們的問題。 但是它也不起作用:
%reset #delete all previous variables
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = a[:][0] #this is how you would have copied a slice of "a" if it was a list
b[2] = 50
a
Out[]:
array([[ 1, 2, 50], #problem persists
[ 4, 5, 6],
[ 7, 8, 9]])
在這種情況下,如果您將numpy數組視為與python列表不同的對象,則可以解決問題。 為了復制numpy數組,您不能執行copy = name_array_to_be_copied[:]
,而是copy = np.copy(name_array_to_be_copied)
。 因此,這將解決我們的別名問題:
%reset #delete all previous variables
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.copy(a)[0] #this is how you copy numpy ndarrays. Calling np.copy() function
b[2] = 50
a
Out[]:
array([[1, 2, 3], #problem solved
[4, 5, 6],
[7, 8, 9]])
PS請注意zeros()
函數。 即使解決了別名問題,您的函數也不會將new_matrix中在矩陣A的同一列中至少具有一個零的列轉換為0(這是我想通過查看錯誤報告的輸出來完成的功能)您的函數[[1, 0, 3], [5, 0, 78], [7, 0, 45]]
[[1,0,3],[5,0,78],[7,3,45]]
[[1, 0, 3], [5, 0, 78], [7, 0, 45]]
,因為它實際上會產生[[1,0,3],[5,0,78],[7,3,45]]
)。 如果您願意,可以嘗試以下方法:
def zeros_2(A):
new_mat = np.copy(A)
for i in range(len(A[0])): #I assume each row has same length.
if 0 in new_mat[:,i]:
new_mat[:,i] = 0
print(new_mat)
return A
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.