#python
Вопрос:
У меня есть список текстовых блоков, подобных этому:
blocks = [
"created may 27th",
"Introduction Foo Bar Bar",
"Lorem te Ipsum",
"Method Participants Foo Foo Bar Procedure Baz"
]
И следующий словарь:
structure = {
"text": [],
"Introduction" : {
"text": []
},
"Method": {
"Participants" : {
"text": []
},
"Procedure": {
"text": []
}
}
}
Я хочу объединить их так, чтобы текстовые блоки оказывались в правильном месте в зависимости от порядка присутствия и возможных строк заголовка в их начале, чтобы создать следующую структуру:
structure = {
"text": ["created may 27th"]
"Introduction" : {
"text": ["Foo Bar Bar", "Lorem te Ipsum"]
}
"Method": {
"Participants" {
"text": ["Foo Foo Bar"]
},
"Procedure": {
"text": ["Baz"]
}
}
Это должно работать для списка любой длины, а также для словаря любой глубины.
Моя интуиция подсказала мне пройтись по текстовому блоку , а затем рекурсивно найти его местоположение, проверив, если block.startswith(header)
, если это так, разделив заголовок и повторив с правильным разделением текстового блока, и в противном случае добавив к выбранному в данный момент значению «текст». Самая большая проблема для меня-это 2 цикла для обхода текстовых блоков и элементов словаря, при этом отслеживая местоположение в словаре и имея возможность перейти к следующему элементу, когда это означает возврат в дерево.
Это то, что я пробовал:
def add_block(block, current_section, header_index=0):
header = list(current_section.keys())[header_index]
if not block.strip().startswith(header):
current_section['text'].append(block)
elif block.startswith(header):
block = block.partition(header)[-1]
add_block(block, current_section[header], header_index 1)
for block in blocks:
add_block(block, structure)
Комментарии:
1. Всегда ли список «блоков» состоит из 4 записей, или введение может охватывать несколько записей списка? (а не только эти двое)?
2. @Amiga500 глубина и длина как ключей словаря, так и элементов списка не ограничены.
3. имеют ли значение теги /n, или вы можете работать без них
4. сначала извлеките все ключи из всех глубин словаря, затем манипулируйте блоками в соответствии с..соедините все элементы в блоке и выполните манипуляцию строками… это должно сработать
5. @sadbro, к сожалению, это не учитывает дубликаты ключей, появляющихся на разных уровнях словаря.
Ответ №1:
Учитывая неограниченную длину ключей/элементов, возможно, лучше всего разбить список «блоков» на подсписки, прежде чем пытаться назначить в структуру.
subLists = {'text':[], 'intro':[], 'method':[]}
posits = ["text", "intro", "method"]
positSwitches = ['Introduction', 'Method', "###"] #Last entry is just an impossible string so we don't go out of range.
iPosits = 0
for line in blocks:
if left(line[:len(positSwitches[iPosits)] == positSwitches[iPosits]:
#We are at first line of a new entry, i.e. moving from text to intro
iPosits = iPosits 1
subLists[posits[iPosits]].append(line)
Вышесказанное должно дать нам словарь, который разбивает список «блоков» на 3 списка для каждого элемента. Исходя из этого, вы можете назначить отдельные функции для заполнения структуры. К сожалению, непроверено, и мне придется бежать — но, надеюсь, это основа для работы!