我正在尝试使用以下代码填充python中空矩阵(列表列表)的对角线:
source=['a','b','c']
rows=[]
for x in source:
rows.append('')
matrix=[]
for x in source:
matrix.append(rows)
print "before populating", matrix
for x in range (0, len(source)):
matrix[x][x]=source[x]
print "after populating", matrix
我意识到这不是实现这一目标的最有效方法,但这实际上似乎是我遇到的最少问题。
我得到的输出是:
[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]
但我希望的输出是这样的:
[['a', '', ''], ['', 'b', ''], ['', '', 'c']]
知道出了什么问题吗?非常感谢!
答案 0 :(得分:4)
for x in source:
matrix.append(rows)
您使用对行的引用填充矩阵。您可以使用行切片制作副本
>> rows = ['a','b','c']
>>> matrix = [rows[:] for _ in range(len(rows))]
>>> matrix
[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]
>>> matrix[1][1]=' '
>>> matrix
[['a', 'b', 'c'], ['a', ' ', 'c'], ['a', 'b', 'c']]
答案 1 :(得分:2)
一个简单的列表理解应该这样做:
In [62]: source=['a','b','c']
In [63]: [[""]*i + [x] + [""]*(len(source)-i-1) for i,x in enumerate(source)]
Out[63]: [['a', '', ''], ['', 'b', ''], ['', '', 'c']]
In [64]: source=['a','b','c','d']
In [65]: [[""]*i + [x] + [""]*(len(source)-i-1) for i,x in enumerate(source)]
Out[65]: [['a', '', '', ''], ['', 'b', '', ''], ['', '', 'c', ''], ['', '', '', 'd']]
答案 2 :(得分:1)
问题出在这个代码上:
rows=[]
for x in source:
rows.append('')
matrix=[]
for x in source:
matrix.append(rows)
您每次都提供相同的参考。
for x in range (0, len(source)):
matrix[x][x]=source[x]
这将修改同一个对象。解决方案:使用副本:
matrix=[]
for x in source:
# use a copy.
matrix.append(rows[:])
答案 3 :(得分:1)
您需要为矩阵中的每一行创建一个新的独立元素行。执行matrix.append(rows)
只会一次又一次地插入对同一列表实例的引用。
请尝试matrix.append(list(rows))
。
对于更复杂的情况,copy
模块可能会有所帮助。
麻烦的根本原因在于Python只处理对象实例的引用,它没有C语言中的“变量”概念,因此在进行赋值时不会复制对象。相反,只有一个新的参考。
答案 4 :(得分:1)
source=['a','b','c']
matrix = [['' if i!=j else source[i] for i in range(len(source))]
for j in range(len(source))]
答案 5 :(得分:1)
其他人已经解释了你的代码发生了什么,但这是另一种选择......
如果您不介意使用numpy
,那么:
import numpy as np
np.diag(['a', 'b', 'c']).tolist()
# [['a', '', ''], ['', 'b', ''], ['', '', 'c']]
如果您要处理矩阵,那么无论如何看numpy
或scipy
可能不是一个坏主意......