Python 中的二维数组是否存在混叠?
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的值,当我returnA时,它仍然被修改:
>>> Matrix = [[1,2,3],[5,0,78],[7,3,45]]
>>> zeros(Matrix)
[[1, 0, 3], [5, 0, 78], [7, 0, 45]]
这个列表有别名吗?如果是这样,您如何在不发生混叠的情况下修改二维数组的元素?非常感谢 <3.
new_mat = A[:]
这会创建列表的副本,而不仅仅是引用它。试一试。
[:]
只是指定了从头到尾的一个切片。例如,您可以 [1:]
表示从元素 1 到末尾,或者 [1:4]
表示元素 1 到 4。查看列表切片。
new_mat = A
不创建新矩阵。您只是为对象命名为 A
。如果它是数字列表的列表,您可能需要使用 copy.deepcopy to create a full copy, and if it's a numpy array you can use the copy 方法。
这可能会对其他人有所帮助。就这样做吧。
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]])
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
我知道列表别名是 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的值,当我returnA时,它仍然被修改:
>>> Matrix = [[1,2,3],[5,0,78],[7,3,45]]
>>> zeros(Matrix)
[[1, 0, 3], [5, 0, 78], [7, 0, 45]]
这个列表有别名吗?如果是这样,您如何在不发生混叠的情况下修改二维数组的元素?非常感谢 <3.
new_mat = A[:]
这会创建列表的副本,而不仅仅是引用它。试一试。
[:]
只是指定了从头到尾的一个切片。例如,您可以 [1:]
表示从元素 1 到末尾,或者 [1:4]
表示元素 1 到 4。查看列表切片。
new_mat = A
不创建新矩阵。您只是为对象命名为 A
。如果它是数字列表的列表,您可能需要使用 copy.deepcopy to create a full copy, and if it's a numpy array you can use the copy 方法。
这可能会对其他人有所帮助。就这样做吧。
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]])
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