2011-03-24 61 views
0

我在Python中使用列表時遇到了奇怪的行爲。我已經實現了一個返回整數列表的方法;特別是,這些都是週期圖表中的每個包括三個節點:Python:列表中的意外訂購

simple_cycles = compute_cycles(graph) 

返回我是這樣的:

[[40000,20000,30000],[700,500,600],[600,500,700],..] 

現在,我需要(1)順序列表中的每個列表中,之後,我需要(2)從整個列表中刪除重複項,並且(3)我需要再次對整個列表進行排序。然後將所需的結果可能如下所示:

[[500,600,700],[20000,30000,40000]] 

任務(1)通過經由compute_cycles返回它們之前排序內部列表來實現。通過執行以下行來獲取任務(2)和(3):

cycles = dict((x[0], x) for x in simple_cycles).values() 

這適用於處理的第一個圖。以下每個圖都失敗,因爲內部列表中的排序有時是錯誤的。我嘗試了最後一個源代碼行兩次,第二個結果不是預期的。例如,我在第二輪得到了爲x:

[29837921, 27629939, 27646591] 

,而不是

[27629939, 27646591, 29837921] 

這一結果在選擇29837921在詞典中,而不是27629939.的關鍵。因此,初始排序與排序(x)似乎已經是錯誤的。但爲什麼?

我試圖重現我的程序之外的行爲,但我不能。在我的應用程序,我解析XML文檔是這樣的:

detector = MyParser() 
handler = MyHandler() 
handler.subscribe(detector.update) 
detector.parse(filename, handler) 

.. 

def parse(self, infile, handler): 
    parser = etree.XMLParser(target=handler) 
    etree.parse(infile, parser) 

當執行,例如,

detector = MyParser() 
handler = MyHandler() 
handler.subscribe(detector.update) 
detector.parse(filename, handler) 
detector.parse(filename, handler) 

然後第二次運行的順序是意外。

我知道,我的源代碼示例不好重現它自己,但也許我在處理列表時錯過了一些基本的Python東西。

更新

這裏是列表的創建:

from networkx import dfs_successors 

def compute_cycles(graph): 
    cycles = [] 
    for node in graph.nodes(): 
    a = graph.successors(node); 
    for a_node in a: 
     b = graph.successors(a_node) 
     for next_node in b: 
     c = graph.successors(next_node); 
     if len(c) > 1: 
      if c[0] == node: 
      cycles.append(sorted([node, a_node, next_node])) 
      elif c[1] == node: 
      cycles.append(sorted([node, a_node, next_node])) 
     else: 
      if c == node: 
      cycles.append(sorted([node, a_node, next_node])) 
     #fi 
     #rof 
    #rof 
    #rof 
    return cycles 

更新

如果犯了大錯:我已經重寫我的Node對象的__repr__功能在圖中使用,以便它返回一個整數。也許,排序失敗,因爲我正在處理的是真實對象而不是整數。我改變了我的調用sort功能是這樣的:

cycles.append(sorted([node, a_node, next_node], key=lambda revision: revision.rev.revid)) 

我得看看是否有差別。節點類定義如下:

class Node(object): 
    def __init__(self, revision, revision_hash): 
    self.rev = revision 
    self.revhash = revision_hash 

    def __repr__(self): 
    return repr((self.rev.revid)) 
+2

沒有機會看到錯誤的代碼,您將不得不希望有人能夠通過心理調試技巧。 – 2011-03-24 10:15:21

+0

您沒有向我們展示將列表排序的代碼。如果您獲得未排序的列表,則問題必須存在。 – interjay 2011-03-24 10:16:28

+2

你是依靠'dict'來排序嗎?它僞隨機地命令事物。 – 2011-03-24 10:21:04

回答

0

我的問題終於解決了。因爲我把對象列表,而不是簡單的Integers,我只好用sort方法如下:

sorted([node, a_node, next_node], key=lambda revision: revision.rev.revid)) 

在這裏,我訪問包含該Integer的成員變量,這是已經被__str__返回。但是,排序時的隱式轉換並不穩定。

3

我不明白爲什麼你使用dict

print sorted(set(tuple(sorted(x)) for x in L)) 
+1

看起來他只使用每個三元組的第一個元素作爲鍵,所以需要'dict'。 – interjay 2011-03-24 10:26:05

+0

@interjay他使用第一個元素作爲鍵的排序方式,這是行不通的,因爲字典不能保證排序。 – juanchopanza 2011-03-24 10:40:15

1

詞典不一定保持順序。他們被允許改變它。把這個放在翻譯:{'a': 1, 'b': 2, 'c': 3}。我得到了{'a': 1, 'c': 3, 'b': 2}

+0

我忘了提及我對字典不感興趣,只是在價值觀上。因此,我在最後執行cycles.sort()。 – labrassbandito 2011-03-24 10:45:15