2014-12-30 4 views
0

나는 논리적 인 도전이 조금있다. 나는 식별자 열과 상호 참조 열을 포함하는 단일 테이블을 Excel에서가집니다. 여러 개의 상호 참조를 나타내는 단일 식별자에 대해 여러 행이있을 수 있습니다.파이썬 - 반복적 인 자기 교차 참조

enter image description here

문자 "X"로 끝나는 모든 기록은 상호 참조 아닌 실제 식별자임을 나타낸다 (이하 기본 예 참조). 각 식별자에 대한 상호 참조 목록을 생성해야하지만 실제 상호 참조 식별자까지 추적해야합니다. 위의 표에서 "A1"을 예제로 사용하면 "A2, A3, B1, B3"과 같이 반환 된 목록이 필요합니다. 목록에 "X"로 끝나는 식별자가 없다는 사실을 알게되면 테이블을 통해 실제 소스 레코드까지 추적됩니다.

모든 아이디어 나 도움을 주시면 감사하겠습니다. 파이썬과 xlrd를 사용하여 테이블을 읽었습니다.

답변

2
t = [ 
    ["a1","a2"], 
    ["a1","a3"], 
    ["a1","ax"], 
    ["ax","b1"], 
    ["ax","bx"], 
    ["bx","b3"] 
] 

import itertools 
def find_matches(t,key): 
    return list(itertools.chain(*[[v] if not v.endswith("x") else find_matches(t,v) for k,v in t if k == key])) 

print find_matches(t,"a1") 

당신은이 빨리 ...

뭔가

t = [ 
    ["a1","a2"], 
    ["a1","a3"], 
    ["a1","ax"], 
    ["ax","b1"], 
    ["ax","bx"], 
    ["bx","b3"] 
] 
class MyGraph: 
    def __init__(self,adjacency_table): 
     self.table = adjacency_table 
     self.graph = {} 
     for from_node,to_node in adjacency_table: 
      if from_node in self.graph: 
       self.graph[from_node].append(to_node)     
      else: 
       self.graph[from_node] = [to_node] 
     print self.graph 
    def find_leaves(self,v): 
     seen = set(v) 
     def search(v): 
      for vertex in self.graph[v]: 
       if vertex in seen: 
        continue 
       seen.add(vertex) 
       if vertex in self.graph: 
        for p in search(vertex): 
         yield p 
       else: 
        yield vertex 
     for p in search(v): 
      yield p 



print list(MyGraph(t).find_leaves("a1"))#,"a1") 
+0

와우처럼 그래프의 인접 행렬로 목록을 치료할 수있다! 매력처럼 작동합니다. 감사! –

+0

솔루션을 제공해 주셔서 감사합니다. 그것은 작은 테이블에서 잘 작동합니다. 그러나 큰 테이블 (6000 레코드)에서 실행할 때 재귀 한계를 초과했습니다. 대형 배열에 대한 대체 접근법에 대한 아이디어가 있습니까? –

+0

순환 참조가 가능합니까? (예 : bx back to ax?) –