连续数的对角矩阵

Diagonal matrix of consecutive numbers

我想在 python 2.7

中的代码下方创建一个对角矩阵
def diag(steps):
    '''
    steps : a positive integer
    '''
    matrix = [[0]*steps]*steps    # matrix of the order step x step
    for i in range(steps + 1):
        matrix[i][i] = i + 1    # i'th' element of 'i'th row
    return matrix

例如:如果 step = 3,我应该得到 [ [1, 0, 0], [0, 2, 0], [0, 0, 3] ]。 但是我得到 [ [1, 2, 3], [1, 2, 3], [1, 2, 3] ] 谁能帮我解决这个错误,请告诉我我的逻辑有什么问题?

1) 为方便起见,您可以考虑使用 numpy,它允许以更 'mathematical' 的方式工作,而不是 python 的列表。 在您的情况下,您可能需要查看 numpy.diag(vector),它创建了一个 len(vector)xlen(vector) 矩阵,其中 matrix[i][i] = vector[i]

根据您的需要,您可以使用 numpy 执行以下操作:

import numpy as np
matrix = np.diag( list(range(1, steps+1))

仅此而已

2) 要回答您的确切问题(如果您由于某种原因不能使用 numpy),您可以将其缩短:

def diag(steps):
    matrix = [ [0]*i+[i+1]+[0]*(steps-i-1) for i in range(steps) ]
    return matrix

通过将数组相乘,您不会创建包含三个不同数组的矩阵。您创建了对同一数组的多个引用。

示例:

> a = [2,2,2]
> b = [a]*3
> print b
[[2, 2, 2], [2, 2, 2], [2, 2, 2]]
> a[1] = 4
> print b
[[2, 4, 2], [2, 4, 2], [2, 4, 2]]
> b[0][0] = 8
> print b 
[[8, 4, 2], [8, 4, 2], [8, 4, 2]]

看到了吗?现在每个 3 元数组的第一个元素都是 8,而不仅仅是 b[0][0]。那是因为它们都是同一个对象。

你必须改变

matrix = [[0]*steps]*steps 

# probably not the best pythonic way but it works
matrix = [[0 for x in range(steps)] for x in range(steps)]