Python中的二维数组中是否存在别名?

时间:2015-02-01 23:37:34

标签: python arrays matrix aliasing

我知道列表别名是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。

4 个答案:

答案 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
相关问题