2010-07-10 29 views
0

我有一些簡單的代碼,代表使用方形布爾矩陣的圖形,其中行/列是節點,true表示兩個節點之間的無向鏈接。我正在用False值初始化此矩陣,然後在存在鏈接的情況下將該值設置爲True。Python列表初始化(通過ref問題)

我相信我初始化列表的方式導致一個單一的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

回答

5

其實,你已經稍微誤解的問題。你相信布爾引用是共享的(這是真的,但並不重要 - 布爾變量是不可變的,所以共享對同一個對象的引用並不意味着太多)。發生的事情是,列表引用是共享的,這是你的麻煩。讓我告訴你:

你的代碼是這樣

[[False] * nodeCount] * 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] 
+0

你是對的,感謝您的詳細解釋 – 2010-07-10 06:47:07

1
self.matrix = [[False] * nodeCount] * nodeCount 

應該像

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