2维列表如何在Python中工作

时间:2012-12-09 14:36:55

标签: python

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

2 个答案:

答案 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维数组结构。