2010-06-28 8 views
3

의 패턴 화 된 데이터에서 중첩 된 목록을 생성, 내가 파이썬 목록에서 사용할 수 이러한 데이터가이에서내용의 테이블을 생성하려면 파이썬

data = [ 
    {title: 'Section 1', level: 1, page_number: 1}, 
    {title: 'Section 1.1', level: 2, page_number: 2}, 
    {title: 'Section 1.2', level: 2, page_number: 3}, 
    {title: 'Section 2', level: 1, page_number: 4}, 
    {title: 'Section 2.1', level: 2, page_number: 5}, 
    {title: 'Section 3', level: 1, page_number: 6}, 
] 

을, 나는 중첩 된 구조의이 종류를 얻을 싶습니다 , 훨씬 더 템플릿 엔진의 사용과 호환 :

toc = [ 
    {title: 'Section 1', page_number: 1, sub: [ 
     {title: 'Section 1.1', page_number: 2, sub: []}, 
     {title: 'Section 1.2', page_number: 3, sub: []}, 
    ]}, 
    {title: 'Section 2', page_number: 4, sub: [ 
     {title: 'Section 2.1', page_number: 5, sub: []},  
    ]}, 
    {title: 'Section 3', page_number: 6, sub: []}, 
] 

이것을 달성하는 방법에 대한 힌트를? 재귀 함수로 시도했지만, 제한된 두뇌에는 많은 까다로운 문제가 있습니다.

도움을 주시면 감사하겠습니다.

편집 : 섹션 항목에 결국에는 자식이 없을 수 있다는 사실이 추가되었습니다. 미안하다.

+0

반복과 루프 및 목록 구조와 같은 스택이 필요하지 않습니다. – Ofir

답변

4

가정 장 아동 장에서는 부모 후에 항상 의미 위하여오고, 누락 된 부모 (생략 수준)이 없습니다 :

import pprint 

data = [ 
    {'title': 'Section 1', 'level': 1, 'page_number': 1}, 
    {'title': 'Section 1.1', 'level': 2, 'page_number': 2}, 
    {'title': 'Section 1.2', 'level': 2, 'page_number': 3}, 
    {'title': 'Section 2', 'level': 1, 'page_number': 4}, 
    {'title': 'Section 2.1', 'level': 2, 'page_number': 42}, 
    {'title': 'Section 2.1.1', 'level': 3, 'page_number': 42}, 
    {'title': 'Section 3', 'level': 1, 'page_number': 42}, 
] 

toc = [] 
stack = [toc] 
for d in data: 
    d['sub'] = [] 
    while d['level'] < len(stack): 
     stack.pop() 
    while d['level'] > len(stack): 
     stack.append(stack[-1][-1]['sub']) 
    stack[-1].append(d) 


pprint.pprint(toc) 

결과 :

[{'level': 1, 
    'page_number': 1, 
    'sub': [{'level': 2, 'page_number': 2, 'sub': [], 'title': 'Section 1.1'}, 
      {'level': 2, 'page_number': 3, 'sub': [], 'title': 'Section 1.2'}], 
    'title': 'Section 1'}, 
{'level': 1, 
    'page_number': 4, 
    'sub': [{'level': 2, 
      'page_number': 42, 
      'sub': [{'level': 3, 
        'page_number': 42, 
        'sub': [], 
        'title': 'Section 2.1.1'}], 
      'title': 'Section 2.1'}], 
    'title': 'Section 2'}, 
{'level': 1, 'page_number': 42, 'sub': [], 'title': 'Section 3'}] 

편집 : 하위 항목이없는 빈 '하위'항목을 갖도록 변경했습니다. 편집 내역의 다른 변형을 참조하십시오.

+0

아, 나는 섹션에 아이도 가질 수 없다는 성명서에 기재해야한다. 그러나 여기에 좋은 것들, 생각을위한 음식 – NiKo

+0

이봐, 네가 빠르다. 좋아, 이제 예상대로 작동합니다. 많은 감사합니다 :) – NiKo

+0

@NiKo 차이점은 섹션에 자식이 없어야한다는 것이 아니라 명확한 경우입니다.이 경우 빈 '하위'항목을 원할 경우입니다. 내 첫 번째 코드는 비어있는 하위를 넣지 않았습니다.이 코드는 않습니다. – unbeli

0

목록의 각 항목을 검토하고 거기에서 새 목록을 작성할 수 있습니다. "Section x.y"가있을 때마다 하위에 추가 할 것입니다.

newData = [] 
curParent = None 
for d in data: 
    # child 
    if d['title'].find('.') > 0: 
    assert curParent # Make sure we have a valid parent dictionary 
    curParent['sub'].append({'title': d['title'], 'page_number': d['page_number']) 
    # parent 
    else: 
    curParent = {'title': d['title'], 'page_number': d['page_number'], 'sub': []} 
    newData.append(curParent) 

2 레벨 또는 3 레벨에서 작동해야합니다. 다른 접근 방식보다 더 많이 필요하면 더 좋을 수도 있습니다. 또한 find ('.')는 다른 제목에서는 작동하지 않을 수도 있지만 수준 필드 (예제에서는 중복 됨) 또는 정규 표현식을 사용하십시오.

+0

네, 많은 중첩 수준을 가질 수 있습니다. 게다가 섹션 제목에 점의 존재를 의지하고 싶지는 않습니다.) – NiKo

+0

완벽하게 맞지 않는 모든 대답을 하향 투표하는 것은 좋지 않습니다. 의도적으로 잘못된 것을 쓴 것처럼 다른 사람보다 다른 접근 방법이었습니다. – tobiw

2

원하는대로 할 수 있습니까?

TITLE, LEVEL, PAGE_NUMBER, SUB = 'title', 'level', 'page_number', 'sub' 
data = [ 
    {TITLE: 'Section 1', LEVEL: 1, PAGE_NUMBER: 1}, 
    {TITLE: 'Section 1.1', LEVEL: 2, PAGE_NUMBER: 2}, 
    {TITLE: 'Section 1.1.1', LEVEL: 3, PAGE_NUMBER: 2}, 
    {TITLE: 'Section 1.2', LEVEL: 2, PAGE_NUMBER: 3}, 
    {TITLE: 'Section 2', LEVEL: 1, PAGE_NUMBER: 4}, 
    {TITLE: 'Section 2.1', LEVEL: 2, PAGE_NUMBER: 5}, 
] 

levels = [ { SUB: [] } ] 
for section in data: 
    section = dict(section) 
    current = section[LEVEL] 
    section[SUB] = [] 
    levels[current-1][SUB].append(section) 
    del levels[current:] 
    levels.append(section) 

toc = levels[0][SUB] 
from pprint import pprint 
pprint(toc) 
+0

매우 좋습니다. 스택이있는 것보다 훨씬 좋을 수도 있습니다. – unbeli

+0

아직 스택이 아니며 약간 다르게 보입니다. 주된 차이점은 전체 섹션을 저장 한 각 레벨의 하위 목록 만 저장한다는 것입니다. 그 문제가 흥미로운 질문이 될 수 있습니다. – Duncan

관련 문제