在函数中生成网格

时间:2011-03-23 08:06:25

标签: python

我们在计算机科学课上创建了一个小脚本,用于通过节点网格找到最短路径,有些是相互关联的,有些则不是。 griddata以不需要定义任何新类的方式存储,即在嵌套列表中。对于n个节点,列表应该有n个元素,每个元素都是一个包含n个元素的列表。

grid[a][b]应返回从节点a到节点b的距离,如果节点未连接或者a和b引用同一节点,则返回0。

例如,列表[[0,2,2],[2,0,2],[2,2,0]]将定义一个包含3个节点的网格,每个节点彼此之间的距离为2。

我编写的脚本应该通过请求与用户的个别距离来定义这样的网格:

def makegrid(nodes):
    res=[[0]*nodes]*nodes
    for i in range(nodes):
        for j in range(nodes):
            if res[i][j]==0 and not i==j:
                x=raw_input('distance node %d zu node %d: ' % (i,j))
                if x:
                    res[i][j]=res[j][i]=int(x)
                else:
                    res[i][j]=res[j][i]=None
    for i in range(nodes):
        for j in range(nodes):
            if res[i][j] is None:
                res[i][j]=0
    return res

我的问题是该功能并没有完全按照我的意图去做,我似乎无法解决原因。它实际上只是运行第一个节点的请求,并以某种方式对所有子列表执行它应该只对第一个节点执行的操作(并忽略不应更改第一个元素)。

任何人都可以帮我搞清楚吗?

2 个答案:

答案 0 :(得分:0)

 res=[[0]*nodes]*nodes

可能不会按照您的想法行事:

>>> nodes = 3
>>> res=[[0]*nodes]*nodes
>>> res
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> res[0][0] = 'echo'
>>> res
[['echo', 0, 0], ['echo', 0, 0], ['echo', 0, 0]]

它不是制作三个单独的列表[0,0,0],而是为您提供对同一列表的三个引用:

>>> id(res[0]), id(res[1]), id(res[2])
(4299671960, 4299671960, 4299671960)

尝试

res=[[0]*nodes for i in range(nodes)]

相反,并阅读,例如,Multiply operator applied to list(data structure)来理解为什么整数和列表的可变性的差异解释了为什么[0] *节点部分似乎表现得像你期望的那样 - 即为什么上面的答案有多个['echo',0,0]副本,而不是['echo','echo','echo'] - 即使最后的“*节点”没有。

答案 1 :(得分:0)

我也陷入了这个陷阱。列表乘法不符合您的预期。看看这个thread

使用列表理解的简单解决方法:

# res=[[0]*nodes]*nodes
res = [[0 for j in range(nodes)] for i in range(nodes)]