2011-03-24 7 views
0

Python으로 목록 작업을하는 동안 이상한 동작이 발생했습니다. Integer리스트를 리턴하는 메소드를 구현했다. 나에게 이런 일을 반환Python : 목록에 예기치 않은 순서가 있음

simple_cycles = compute_cycles(graph) 

: 특히, 그 사이클 그래프 내의 각 등 3 개 노드입니다

[[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] 

이 결과를 따라서 대신 27629939.의 사전 키로 29,837,921 선택에 초기 순서를 정렬하여 (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 

업데이트

큰 실수를 한 경우 : 여기에 업데이트

은리스트의 창조 내 노드 객체의 __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

잘못된 코드를 볼 기회가 없으면 심령술 디버깅 기술을 가진 사람이 팝업을 열어 줄 것을 기대해야합니다. –

+0

목록을 정렬하는 코드를 표시하지 않았습니다. 정렬되지 않은 목록을 얻는다면, 문제가 거기에 있어야합니다. – interjay

+2

'dict'을 사용하여 정렬 하시겠습니까? 물건을 의사 무작위로 주문합니다. –

답변

0

내 문제가 마침내 해결되었습니다. 여기

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

, 이미 __str__에 의해 반환 된 Integer를 포함하는 멤버 변수를 접근하고있다 : 나는 간단한 Integers 대신 목록에 물건을 올려 때문에 다음과 같이 나는 sort 방법을 사용했다. 그러나 정렬 중 암시 적 변환은 안정적이지 않습니다.

3

당신이 dict를 사용하는 이유를 이해하지 않습니다 다음과 같이 노드 클래스는 정의된다.

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

그는 각 트리플의 첫 번째 요소 만 키로 사용하는 것처럼 보입니다. 따라서 'dict'이 필요할 것입니다. – interjay

+0

@interjay 그는 정렬 수단으로 키의 첫 번째 요소를 사용하고 있으며, 사전은 순서를 보장하지 않으므로 작동하지 않습니다. – juanchopanza

1

사전은 반드시 주문을 유지하지 않습니다. 그들은 그것을 바꿀 수 있습니다. 통역사에 넣어 : {'a': 1, 'b': 2, 'c': 3}. 나는 {'a': 1, 'c': 3, 'b': 2}을 얻었습니다.

+0

나는 값에 대해서만 내가 사전에 관심이 없다는 것을 잊어 버렸다. 따라서, 나는 결국 cycles.sort()를 실행하고있다. – labrassbandito