我有一些简单的代码,它使用方形布尔矩阵表示图形,其中行/列是节点,而true表示两个节点之间的无向链接。我正在使用False值初始化此矩阵,然后将值设置为True,其中存在链接。
我相信我初始化列表的方式是导致给定行中的每个单元格引用单个bool实例。结果是,如果我将任何单元格设置为True,则该行中的所有其他单元格也将变为True。
我应该如何初始化我的方形矩阵,以便所有值都为false但是没有与其他单元格共享?
import sys
class Graph(object):
def __init__(self, nodeCount, links):
self.matrix = [[False] * nodeCount] * nodeCount
for l in links:
self.matrix[l[0]][l[1]] = True
def __str__(self):
s = " "
for i in range(len(self.matrix)):
s += str(i) + " "
s += "\n"
for r in range(len(self.matrix)):
s += str(r) + " "
for c in range(len(self.matrix)):
s += str(self.matrix[c][r])[0] + " "
s += "\n"
return s
g = Graph(5, [(2,3)])
print g
此外,在GIST
上答案 0 :(得分:5)
实际上,你有点误解了这个问题。您认为布尔引用是共享的(这是真的,但并不重要 - 布尔值是不可变的,因此共享对同一对象的引用并不意味着太多)。发生的事情是列表引用是共享的,这引起了你的麻烦。让我告诉你:
您的代码就是这个
[[False] * nodeCount] * nodeCount
当您使用nodeCount
引用False的单个列表获得nodeCount
个引用时,会发生什么。将一个序列乘以整数给出一个带有重复引用的序列 - 它们不是副本,而是别名。
>>> x = [False] * 3
>>> y = [x] * 3
>>> y[0] is y[1]
True
>> # your problem
>>> y[0][0] = True
>>> y[1]
[True, False, False]
因此,在这种情况下,这意味着您无法更改单个行,因为所有行都是相同的列,并且更改一行会更改所有行。
要解决此问题,请为每行创建新列表:
[[False]*nodeCount for _ in xrange(nodeCount)]
示例:
>>> y = [[False]*3 for _ in xrange(3)]
>>> y[0] is y[1]
False
>>> y[0][0] = True
>>> y[1]
[False, False, False]
答案 1 :(得分:1)
self.matrix = [[False] * nodeCount] * nodeCount
应该是
self.matrix = [[False] * nodeCount for _ in range(nodeCount)]