1

我正在做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 中的数组,所以我以相同的方式使用它们。

4

2 回答 2

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()调用都有相同的结果,表明它们都是相同的 list

于 2012-12-09T14:42:35.580 回答
0

在第一行,使用这个:

f = [[0] * 21 for _ in xrange(21)]

您编写的内容将创建一个长度为 21 的列表(这就是内部[0]*21所做的),然后创建一个包含相同内部列表 21 次的外部列表。这意味着每当您修改内部列表中的元素时,它会在所有副本中被修改,即在矩阵的每一行中。

对于它的价值,您可能想查看该numpy模块(当然首先安装NumPy),它为您提供了一个“正确的”n 维数组结构。

于 2012-12-09T14:40:45.090 回答