Как напечатать линии в разделенных линиях отступом? - PullRequest
0 голосов
/ 30 января 2020

У меня есть строка:

text = '''TextTextTextTextTextTextTextTextText1
        TextTextTextTextTextTextTextTextText1
    TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText3
        TextTextTextTextTextTextTextTextText3
        TextTextTextTextTextTextTextTextText3
    TextTextTextTextTextTextTextTextText4
        TextTextTextTextTextTextTextTextText4
        TextTextTextTextTextTextTextTextText4'''

Я хочу разбить эту строку по отступам и добавить их в список. Вот мой текущий код:

nr_lines = 0
indent_dict = {}
for line in summary1.splitlines(True):
    print(line)
    print("------------------------------")
    nr_lines+=1
    whitespaces_count = len(line) - len(line.lstrip())
    indent_dict[nr_lines] = whitespaces_count
print(indent_dict)

list_of_values = []

# Removed first key with value (indent) = 0
indent_dict_without = dict(indent_dict)
key = 1
del indent_dict_without[key]

# Adding values from dict to list
for key, value in indent_dict_without.items():
    list_of_values.append(value)
print(list_of_values)

# Finding minimum value
x = min(list_of_values)

list_of_small = []

for nr in list_of_values:
    if nr == x:
        list_of_small.append(nr)

print(list_of_small)

# Finding which line have all smallest indent
n = 0
key_1 = []
for key, value in indent_dict.items():
    if value == list_of_small[n]:
        key_1.append(key)
print(key_1)

Вывод:

{1: 0, 2: 12, 3: 8, 4: 12, 5: 12, 6: 12, 7: 12, 8: 8, 9: 12, 10: 12, 11: 8, 12: 12, 13: 12} # dict with line and value (indent)
[12, 8, 12, 12, 12, 12, 8, 12, 12, 8, 12, 12] # list with indents
[8, 8, 8] # the smallest indents
[3, 8, 11] # lines for smallest indents

Теперь я не знаю, как разделить и добавить эти 4 части в качестве элементов списка:

list = ['TextTextTextTextTextTextTextTextText1
            TextTextTextTextTextTextTextTextText1',
        'TextTextTextTextTextTextTextTextText2
            TextTextTextTextTextTextTextTextText2
            TextTextTextTextTextTextTextTextText2
            TextTextTextTextTextTextTextTextText2
            TextTextTextTextTextTextTextTextText2',
        'TextTextTextTextTextTextTextTextText3
            TextTextTextTextTextTextTextTextText3
            TextTextTextTextTextTextTextTextText3',
        'TextTextTextTextTextTextTextTextText4
            TextTextTextTextTextTextTextTextText4
            TextTextTextTextTextTextTextTextText4']

Должен ли я создавать новую переменную и добавлять строки одну за другой до нового отступа?

Ответы [ 2 ]

1 голос
/ 30 января 2020

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

text = '''TextTextTextTextTextTextTextTextText1
    TextTextTextTextTextTextTextTextText1
TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText2
TextTextTextTextTextTextTextTextText3
    TextTextTextTextTextTextTextTextText3
    TextTextTextTextTextTextTextTextText3
TextTextTextTextTextTextTextTextText4
    TextTextTextTextTextTextTextTextText4
    TextTextTextTextTextTextTextTextText4'''


lines = text.split('\n')
# Count spaces in each line
indent_lst = [line.count(' ') for line in text.splitlines(True)]
# Find where indentation changes
indices = []
for idx in range(len(indent_lst[1:])): # Start at second element in list
    # Here I assume, that the indentation is constant. A change from more spaces to fewer spaces means,
    # that a new block has started
    if indent_lst[idx-1] > indent_lst[idx]: # Look back at previous element and compare with current
        indices.append(idx)

final_lst = []
# Use slicing to append from block to block
for idx in range(len(indices)):
    if indices.index(indices[idx]) == (len(indices) -1 ): # Take care of last block
        final_lst.append(''.join(lines[indices[idx]:]))
    else:
        final_lst.append(''.join(lines[indices[idx]:indices[idx+1]])) # Add block to final list
print(final_lst)

Вот результат:

['TextTextTextTextTextTextTextTextText1        TextTextTextTextTextTextTextTextText1', '    TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2', '    TextTextTextTextTextTextTextTextText3        TextTextTextTextTextTextTextTextText3        TextTextTextTextTextTextTextTextText3', '    TextTextTextTextTextTextTextTextText4        TextTextTextTextTextTextTextTextText4        TextTextTextTextTextTextTextTextText4']

Я надеюсь, что это уже поможет вам и не стесняйтесь спрашивать, если у вас есть вопросы!

1 голос
/ 30 января 2020

Если я вас правильно понимаю, вы хотите разбить текст на параграфы, основываясь на строках с наименьшим отступом.

Способ, которым я хотел бы подойти к этому, заключается в следующем. Я бы создал defaultdict с ключом в качестве номера пробелов, составляющих отступ, и в качестве значения список со всеми индексами строк, имеющих этот счет отступов:

from collections import defaultdict

text = '''TextTextTextTextTextTextTextTextText1
        TextTextTextTextTextTextTextTextText1
    TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
        TextTextTextTextTextTextTextTextText2
    TextTextTextTextTextTextTextTextText3
        TextTextTextTextTextTextTextTextText3
        TextTextTextTextTextTextTextTextText3
    TextTextTextTextTextTextTextTextText4
        TextTextTextTextTextTextTextTextText4
        TextTextTextTextTextTextTextTextText4'''

def count_indentation(line):
    return len(line) - len(line.lstrip())

lines = text.splitlines(keepends=False)
indent_dict = defaultdict(list)
for idx, line in enumerate(lines):
    if count_indentation(line) > 0:
        indent_dict[count_indentation(line)].append(idx)

Теперь indent_dict выглядит следующим образом:

defaultdict(list, {8: [1, 3, 4, 5, 6, 8, 9, 11, 12], 4: [2, 7, 10]})

Далее мы берем наименьший ключ, чтобы найти индексы соответствующих строк:

smallest_indent = min(indent_dict)
line_idexes_smallest_indents = indent_dict[smallest_indent]

Результат line_idexes_smallest_indents равен [2, 7, 10]. Индексирование начинается с нуля, поэтому мои индексы на единицу меньше вашего результата. Теперь нам нужно разбить наш оригинальный текст по этим индексам.

def partition(lines, indices):
    return [''.join(lines[i:j]) for i, j in zip([0]+indices, indices+[None])]

partition(lines, line_idexes_smallest_indents)

Результат:

['TextTextTextTextTextTextTextTextText1        TextTextTextTextTextTextTextTextText1',
 '    TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2        TextTextTextTextTextTextTextTextText2',
 '    TextTextTextTextTextTextTextTextText3        TextTextTextTextTextTextTextTextText3        TextTextTextTextTextTextTextTextText3',
 '    TextTextTextTextTextTextTextTextText4        TextTextTextTextTextTextTextTextText4        TextTextTextTextTextTextTextTextText4']
...