我创建一个矩阵,该矩阵有4行和5列,填充有零。然后,我将一些值放入第一行(第0行),并希望使用函数计算第二行(第1行)的值。我的代码是:
string
但是打印结果是:
x = [0,1,2,1,0]
u=[[0]*(len(x))]*(4)
u[0]=x
for n in range(0,1):
print u
for j in range(1,4):
u[n+1][j]=u[n][j]-(u[n][j+1]-u[n][j-1])
print 'Value %.f at position %.f %.f' %(u[n+1][j],n+1,j)
print u
我不明白为什么程序要计算第1行和第1、2和3列的值,但是在循环之后第2和3行也使用值。我希望打印的结果是:
[[0, 1, 2, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Value -1 at position 1 1
Value 2 at position 1 2
Value 3 at position 1 3
[[0, 1, 2, 1, 0], [0, -1, 2, 3, 0], [0, -1, 2, 3, 0], [0, -1, 2, 3, 0]]
答案 0 :(得分:1)
简而言之,当您将[0]*(len(x))
乘以一个列表时,将得到一个包含5个引用数字0的元素的列表。我们将此列表称为“ Joe”。表达式的其余部分将创建另一个引用“ Joe”的列表,该列表乘以4次,从而得到一个列表,其中包含对同一“ Joe”(列表)的4个引用。您认为实际上只有10个值,而您只有20个值: 1 数字0的值,列表中的 5 值,所有值都引用数字0 ,最外面的列表中的 4 个值,全部包含5个值对列表的引用。 (1 + 5 + 4 = 10,也许可以更好地理解为图表)
我将尝试进一步细分它,特别是针对您的代码:
(我们将尝试从u=[[0]*(len(x))]*(4)
到u=[[0]*5]*4
整理一下您的表达式)
然后可以将其扩展为:
element=[0]
line=[element*5]
u=line*4
关键是,当我们print line
时,我们将会得到
[[0, 0, 0, 0, 0]]
这意味着
u=line*4
与
相同u=[[0, 0, 0, 0, 0]]*4`
因此,当您print u
时,您会得到预期的结果
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
现在,当您修改“单元格”之一时,在第三行说第三个单元格
u[2][2]=1
您得到
[[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]]
您可能会说这是奇怪且不一致的:element
和line
都是列表,为什么值只能“垂直”复制?
这种奇怪是由于以下事实:在Python容器(例如列表)中仅使用引用:
每个对象都有一个标识,一个类型和一个值。一旦创建了对象,其身份就永远不会改变。您可能会认为它是对象在内存中的地址。
某些对象包含对其他对象的引用;这些称为容器。容器的示例是元组,列表和字典。引用是容器值的一部分。 (但引用的项目的实际值不是)
(有关更多信息,请参见Python的data model)
...。您可以将*运算符想像成这样:
def multiply(list, times):
result = []
for i in range(times):
value=list[i % len(list)]
result.append(value)
return result
将您的代码重写为
u = multiply([multiply([0],5)],4)