我在做Project Euler Problem 15。我使用了正确的算法,但似乎没有用。这是我的代码:
f = [[0] * 21] * 21
# init the list
for i in range(21):
f[0][i] = 1
f[i][0] = 1
for i in range(21):
for j in range(21):
f[i][j] = f[i-1][j] + f[i][j-1]
print f[20][20]
当我完成列表的初始化时,我将其打印出来。我希望它像[[1, 1, 1...], [1, 0, 0...]...]
,但它转为[[1, 1, 1...], [1, 1, 1...]...]
,我无法理解为什么。
我曾经使用类C语言,我认为Python中的列表有点像C中的数组,所以我以相同的方式使用它们。
答案 0 :(得分:4)
当乘以列表时,您不是创建单独的列表,而是创建多个引用到相同的列表。
相反,这样做:
f = [[0 for _ in range(21)] for _ in range(21)]
使用id()
功能时,您可以看到区别:
>>> f = [[0]*21]*21
>>> for nested in f[:3]:
... print id(nested)
...
4523317152
4523317152
4523317152
>>> f = [[0 for _ in range(21)] for _ in range(21)]
>>> for nested in f[:3]:
... print id(nested)
...
4523317512
4523317440
4523317656
单独的对象具有单独的内存ID值,而您的列表对每个id()
调用都有相同的结果,显示它们都是相同的列表。
答案 1 :(得分:0)
在第一行中,使用:
f = [[0] * 21 for _ in xrange(21)]
你写的内容将创建一个长度为21的列表(这就是内部[0]*21
所做的),然后创建一个包含相同内部列表21次的外部列表。这意味着无论何时修改内部列表中的元素,都会在 all 副本中修改它,即在矩阵的每一行中进行修改。
对于它的价值,您可能需要查看numpy
模块(当然首先安装NumPy),它会为您提供“正确的”n维数组结构。