2016-08-28 2 views
2

У меня есть список оглавления, что я хотел бы создать в отступе строкуPython создать отступ строку из списка

list = ['1. Section', '1.1 Subsection', '1.1.1 Subsubsection', '1.1.2 Subsubsection', '2. Section', '2.1 Subsection', '2.1.1 Subsubsection', '2.1.2 Subsubsection', '2.2 Subsection', '2.2.1 Subsubsection'] 

и желаемый результат заключается в следующем:

1. Section 
    1.1 Subsection 
     1.1.1 Subsubsection 
     1.1.2 Subsubsection 
2. Section 
    2.1 Subsection 
     2.1.1 Subsubsection 
     2.1.2 Subsubsection 
    2.2 Subsection 
     2.2.1 Subsubsection 

Я попытался это:

toc = '' 

for tocitem in list: 
    if re.match('(\d+)\.', tocitem): 
     toc += tocitem + '\n' 
    elif re.match('(\d+)\.(\d+)', tocitem): 
     toc += '\t' + tocitem + '\n' 
    else: 
     toc += '\t\t' + tocitem + '\n' 

Но язычки не признаются, что я получаю эту

1. Section 
1.1 Subsection 
1.1.1 Subsubsection 
1.1.2 Subsubsection 
2. Section 
2.1 Subsection 
2.1.1 Subsubsection 
2.1.2 Subsubsection 
2.2 Subsection 
2.2.1 Subsubsection 

Что я делаю неправильно?

+0

Пожалуйста, поставьте это как ответ, так что я могу принять его :) Благодаря! –

ответ

1

Обратный порядок if re.match(...) утверждений. Все ваши предметы проходят первый тест, поэтому код никогда не входит в блок elif.

+0

Я просто положил то же самое, что ответить ...: D –

+0

freakish был первым;) Я дам вам, ребята, upvote для усилий :) –

+0

Я победил нас за секунды, чтобы выиграть золото SO: D –

1

Попробуйте это:

toc = '' 
for tocitem in list: 
    if re.match('(\d+)\.(\d+)\.', tocitem): 
     toc += '\t\t' + tocitem + '\n' 
    elif re.match('(\d+)\.(\d+)', tocitem): 
     toc += '\t' + tocitem + '\n' 
    else: 
     toc +=tocitem + '\n' 
1

Во-первых, я использую lst вместо list, потому что list функция ...

Далее, для этой работы вы должны соответствовать первым длинный
серии чисел, а затем работать до кратчайшего.

toc = '' 

for tocitem in lst: 
    if re.match('(\d+)\.(\d+)\.(\d+)', tocitem): 
     toc += '\t\t' + tocitem + '\n' 
    elif re.match('(\d+)\.(\d+)', tocitem): 
     toc += '\t' + tocitem + '\n' 
    else: 
     toc += tocitem + '\n' 

И есть выход:


1. Section 
     1.1 Subsection 
       1.1.1 Subsubsection 
       1.1.2 Subsubsection 
2. Section 
     2.1 Subsection 
       2.1.1 Subsubsection 
       2.1.2 Subsubsection 
     2.2 Subsection 
       2.2.1 Subsubsection 

Теперь это касается вашего вопроса.
Однако, я хотел бы сделать это без if с, более систематически
следующим образом:

toc = '' 

for tocitem in lst: 
    s = re.match(r'\S+', tocitem).group(0) 
    digits = [x for x in s.split('.') if x.strip() != ''] 
    toc += (len(digits) - 1) * 4 * ' ' + tocitem + '\n' 

Регулярное выражение просто находит первый участок вплоть до пространства,
затем расщепляется на точку и принять все пункты, которые не являются пустыми.

1

Первое условие if соответствует другим случаям. Поэтому вам нужно переключить заказ или сделать более общий подход:

toc = '' 
for tocitem in list: 
    number = tocitem.split()[0] 
    toc += '\t' * number.strip('.').count('.') + tocitem + '\n' 
1

Действительно интересный вопрос! вот возможное решение, предполагающее, что ваши данные не отсортированы.

python 2.х:

import re 
import random 

# Unordered data!!! 
lst = ['1. Section', '1.1 Subsection', '1.1.1 Subsubsection', '1.1.2 Subsubsection', '2. Section', 
     '2.1 Subsection', '2.1.1 Subsubsection', '2.1.2 Subsubsection', '2.2 Subsection', '2.2.1 Subsubsection'] 
random.seed(1) 
random.shuffle(lst) 

# Creating TOC 
data = {v[:v.rindex(" ")]: v for v in lst} 
keys = sorted(data.keys(), key=lambda x: map(
    int, filter(lambda x: x, x.split('.')))) 

toc = '' 
for k in keys: 
    number = data[k].split()[0] 
    toc += '\t' * number.strip('.').count('.') + k + '\n' 

print toc 
+0

У меня было 3 списка, которые я объединил и отсортировал с помощью 'list (heapq.merge (разделы, подразделы, подсекции))' были 'разделами',' подразделы' и 'подписок 'являются соответствующие списки :) Но это выглядит интересно :) –

+0

@dingo_d Fair достаточно, я просто хотел дать другой ответ другим хорошим ;-) – BPL

1

Учитывая упорядоченный список с заголовками разделов:

li = ['1. Section', '1.1 Subsection', '1.1.1 Subsubsection', '1.1.2 Subsubsection', '2. Section', '2.1 Subsection', '2.1.1 Subsubsection', '2.1.2 Subsubsection', '2.2 Subsection', '2.2.1 Subsubsection'] 

Вы можете сделать:

print '\n'.join(['\t'*(len(re.findall(r"(\d+)", s))-1)+s for s in li]) 

Печать:

1. Section 
    1.1 Subsection 
     1.1.1 Subsubsection 
     1.1.2 Subsubsection 
2. Section 
    2.1 Subsection 
     2.1.1 Subsubsection 
     2.1.2 Subsubsection 
    2.2 Subsection 
     2.2.1 Subsubsection 

Учитывая список в случайном порядке что вы хотите сортировать первый:

li=['2.1.2 Subsubsection', '2.1.1 Subsubsection', '1.1.1 Subsubsection', '1. Section', '2. Section', '1.1 Subsection', '2.2 Subsection', '2.2.1 Subsubsection', '2.1 Subsection', '1.1.2 Subsubsection'] 

Вы можете сортировать и отступы в одном цикле без регулярных выражений:

for n, s in sorted([(ni, si) for ni, _, si in [x.partition(' ') for x in li]]): 
    print '\t'*(len([e for e in n.split('.') if e])-1)+n, s 

распечаток:

1. Section 
    1.1 Subsection 
     1.1.1 Subsubsection 
     1.1.2 Subsubsection 
2. Section 
    2.1 Subsection 
     2.1.1 Subsubsection 
     2.1.2 Subsubsection 
    2.2 Subsection 
     2.2.1 Subsubsection 
Смежные вопросы