【问题标题】:How can I iterate through a list of strings in Python and concatenate the ones that belong to a tag?如何遍历 Python 中的字符串列表并连接属于标签的字符串?
【发布时间】:2020-04-30 17:13:37
【问题描述】:

在 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"]

在这个列表中,有带有标签的元素和其他没有标签的元素。这个想法是具有此标签的元素是“标题”,直到下一个标签的以下元素是它的内容。

如何将列表中属于 header 的元素连接成两个大小相等的列表:

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)

对如何组合这些文本以使它们一一对应有什么想法吗?

谢谢!

【问题讨论】:

    标签: python python-3.x string list


    【解决方案1】:

    假设每个标题之后的所有元素都是该标题的内容,并且第一个元素始终是标题 - 您可以使用itertools.groupby

    key可以是元素是否有header标签,这样header的内容就会在它之后被分组:

    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)
    

    【讨论】:

    • @Pythoner 很乐意为您提供帮助。我还添加了有关您当前方法的注释,以供参考
    【解决方案2】:

    您可以在迭代列表时将标题和内容收集到 collections.defaultdict 中。然后将键和值拆分为最后的headerscontent 列表。我们可以通过简单地检查字符串 str.startswith "&lt;h" 来检测标题。

    我还使用continue 语句在找到标头后立即进入下一个迭代。也可以在这里使用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'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 2017-04-24
      相关资源
      最近更新 更多