我知道列表别名是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数组的元素而不会出现锯齿?非常感谢muhc< 3。
答案 0 :(得分:3)
new_mat = A
不会创建新矩阵。您只是为您知道为A
的对象指定了新名称。如果它是一个数字列表列表,您可能希望使用copy.deepcopy创建完整副本,如果它是一个numpy数组,您可以使用copy方法。
答案 1 :(得分:1)
new_mat = A[:]
这会创建列表的副本,而不仅仅是引用它。试一试。
[:]
只是从头到尾指定一个切片。您可以拥有[1:]
,它可以从元素1到结尾,或[1:4]
,例如,它将是元素1到4。查看关于此的列表切片。
答案 2 :(得分:1)
这可能有助于其他人。就这样做。
import copy
def zeros(A):
new_mat = copy.deepcopy(A)
答案 3 :(得分:1)
QUICK EXPLANATION
如果你想让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
THOROUGH EXPLANATION
假设我们不希望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]])
P.S。注意zeros()
功能。即使在修复了别名问题之后,你的函数也没有将new_matrix中的列转换为0,这些列在矩阵A的同一列中至少有一个零(这是我认为你想通过查看错误报告的输出来实现的你的函数[[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