Как я могу перебрать список строк в Python и объединить те, которые принадлежат тегу? - PullRequest
2 голосов
/ 30 апреля 2020

При переборе списка элементов в Python 3, как я могу "изолировать" содержимое между интересующими элементами?

У меня есть список:

list = ["<h1> question 1", "question 1 content", "question 1 more content", "<h1> answer 1", "answer 1 content", "answer 1 more content", "<h1> question 2", "question 2 content", "<h> answer 2", "answer 2 content"]

В этом списке есть элементы с тегом и другие без него. Идея состоит в том, что элемент, имеющий этот тег, является «заголовком», а следующие элементы до следующего тега являются его содержимым.

Как объединить элементы списка, которые принадлежат заголовку, чтобы иметь два Списки одинакового размера:

headers = ["<h1> question 1", "<h1> answer 1", "<h1> question 2", "<h> answer 2"]
content = ["question 1 content question 1 more content", "answer 1 content answer 1 more content", "question 2 content", "answer 2 content"]

Если длина этих двух списков одинакова, в данном случае по 4 элемента в каждом.

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

list = ["<h1> question 1", "question 1 content", "question 1 more content", "<h1> answer 1", "answer 1 content", "answer 1 more content", "<h1> question 2", "question 2 content", "<h> answer 2", "answer 2 content"]

headers = []
content = []

for i in list:
    if "<h1>" in i:
        headers.append(i)

    if "<h1>" not in i:
        tempContent = []
        tempContent.append(i)
        content.append(tempContent)

Есть мысли о том, как объединить эти тексты, чтобы они отображались с 1 на 1?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 30 апреля 2020

Предполагая, что после каждого заголовка все элементы являются содержимым этого заголовка, и что первый элемент всегда является заголовком - вы можете использовать itertools.groupby.

key может указывать, имеет ли элемент тег заголовка, и таким образом содержимое этого заголовка будет группироваться сразу после него:

from itertools import groupby

lst = ["<h1> question 1", "question 1 content", "question 1 more content", "<h1> answer 1", "answer 1 content", "answer 1 more content", "<h1> question 2", "question 2 content", "<h> answer 2", "answer 2 content"]

headers = []
content = []

for key, values in groupby(lst, key=lambda x: "<h" in x):
    if key:
        headers.append(*values)
    else:
        content.append(" ".join(values))

print(headers)
print(content)

Дает:

['<h1> question 1', '<h1> answer 1', '<h1> question 2', '<h> answer 2']
['question 1 content question 1 more content', 'answer 1 content answer 1 more content', 'question 2 content', 'answer 2 content']

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

headers = []
content = []
temp_content = None

for i in list:
    if "<h" in i:
        if temp_content is not None:
            content.append(" ".join(temp_content))
            temp_content = []
        headers.append(i)

    else:
        temp_content.append(i)
1 голос
/ 30 апреля 2020

Вы можете собирать свои заголовки и содержимое в collections.defaultdict при повторении списка. Затем разделите ключи и значения на списки headers и content в конце. Мы можем обнаружить заголовки, просто проверив, является ли строка str.startswith "<h".

Я также использую оператор continue для go до следующей итерации сразу после нахождения заголовка. Здесь также можно использовать оператор else.

from collections import defaultdict

lst = [
    "<h1> question 1",
    "question 1 content",
    "question 1 more content",
    "<h1> answer 1",
    "answer 1 content",
    "answer 1 more content",
    "<h1> question 2",
    "question 2 content",
    "<h> answer 2",
    "answer 2 content",
]

header_map = defaultdict(list)

header = None
for item in lst:
    if item.startswith("<h"):
        header = item
        continue
    header_map[header].append(item)

headers = list(header_map)
print(headers)

content = [" ".join(v) for v in header_map.values()]
print(content)

Выход:

['<h1> question 1', '<h1> answer 1', '<h1> question 2', '<h> answer 2']
['question 1 content question 1 more content', 'answer 1 content answer 1 more content', 'question 2 content', 'answer 2 content'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...