2013-09-05 4 views
0

문제 설명 :경로 이름의 파이썬 중첩 사전

비 재귀 솔루션을 사용하여 중첩 된 사전에 OS 경로를 저장합니다.

목표 :

사용할 수있는 가장 빠른 방법을 사용하여 파이썬 사전으로 디렉토리 트리를 나타냅니다.

주의 할 (들) :

재귀가 코드에 가장 쉬운이었다 그러나 사용할 수있는 금식 방법은 아닙니다.

선형 솔루션 :

def store_into_bucket(bucket): 
    ''' 
    Result should look like this: {'1': {'2': {'3': '/1/2/3'}}} 

    Algorithm looks like this, for linear solution: 

    bucket[toks[0]] = {} 
    bucket[toks[0]][toks[1]] = {} 
    bucket[toks[0]][toks[1]][toks[2]] = '/'+('/'.join(toks)) 
    ''' 
    path = '/1/2/3' 
    toks = [t for t in path.split('/') if (len(t) > 0)] 

    lines = [] 
    ops = ['[toks[%s]]' % (i) for i in xrange(0,len(toks))] 
    n = (len(toks)-1) 
    for i in xrange(0,len(toks)): 
     s = 'bucket%s' % (''.join(ops[0:i])) 
     lines.append('%s = %s' % (s,'{}' if (i < n) else '"%s"'%('/'+('/'.join(toks))))) 
    __namespace__ = {} 
    __namespace__['toks'] = toks 
    exec('\n'.join(lines)) in __namespace__ 
    return __namespace__['bucket'] 

print store_into_bucket({}) 

질문 :

이 목표를 달성하기위한 이것보다 더 나은 솔루션이 있습니다.

감사합니다.

+0

오늘 찾아 보니 오늘이 사실을 발견했습니다. http://stackoverflow.com/questions/16547643/convert-a-list-of-delimited-strings-to-a-tree-nested-dict-using-python –

답변

3

쓰기 쉬운 재귀 함수는 N 레벨의 스택으로 확장 한 다음 스택을 통해 다시 축소 될 때 아래에서 위로 사전을 작성합니다. 그것은 이것을하기위한 쉬운 방법에 대한 힌트를 제공합니다 ... 뒤로 이동하십시오.

path = '1/2/3' 
toks = [t for t in path.split('/') if t] 
ret = path 
for tok in reversed(toks): 
    ret = {tok: ret} 
return ret 
+0

멋지다. 정말로 굉장하다! !! 하지만 ... 원래 문제는 "사용 가능한 가장 빠른 방법을 사용하여 디렉토리 트리를 파이썬 사전으로 표시하는 것"이었습니다. 단일 인스턴스가있는 경우 데이터의 모양을 단일 인스턴스로 가져 오는 매끄러운 방법입니다. 이런 식으로 저장하는 파일이 수백 개있을 때 문제가 좀 더 재미 있습니다. 다시 시도 하시겠습니까? – user713588

+0

흠. 재귀가 최선의 해결책이 아닐까요? 왜 이런 식으로하지 않습니다 : http://stackoverflow.com/questions/8484943/construct-a-tree-from-list-os-file-paths-python-performance-dependent 작동합니까? –

0

영감 비트 ...

생성기! 이 방법에 대해

:

데프 (위) : 도보

from vyperlogix import misc 

try: 

    __stack__ = [] 

    while (1): 

     for k,v in top.iteritems(): 

      yield k if (misc.isDict(v)) else v 

      if (misc.isDict(v)): 

       __stack__.append(v) 

     top = __stack__.pop() if (len(__stack__) > 0) else None 

     if (not top): 

      raise StopIteration 

except: 

    raise StopIteration 

raise StopIteration 

비트 원유하지만이 ... 아니 재귀를 작동하지 않을 것 같다!