代码之家  ›  专栏  ›  技术社区  ›  Eric Schoonover thSoft

Python列表初始化(按ref问题)

  •  0
  • Eric Schoonover thSoft  · 技术社区  · 14 年前

    我有一些简单的代码,它使用一个正方形布尔矩阵表示一个图形,其中行/列是节点,true表示两个节点之间的无向链接。我用假值初始化这个矩阵,然后在存在链接的地方将值设置为真。

    我相信我初始化列表的方式会导致给定行中的每个单元格引用一个bool实例。结果是,如果我将任何单元格设置为True,则该行中的所有其他单元格也将变为True。

    我应该如何初始化我的方阵,使所有的值都是假的,但没有一个是共享的引用与其他单元格?

    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

    2 回复  |  直到 14 年前
        1
  •  5
  •   Devin Jeanpierre    14 年前

    你的密码是这个

    [[False] * nodeCount] * nodeCount
    

    nodeCount 对单个列表的引用 节点计数 引用False。将一个序列乘以一个整数得到一个包含重复引用的序列——它们不是副本,而是别名。

    >>> 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]
    
        2
  •  1
  •   Bwmat    14 年前
    self.matrix = [[False] * nodeCount] * nodeCount
    

    self.matrix = [[False] * nodeCount for _ in  range(nodeCount)]