首页 > 解决方案 > 使用 Python 3 优化删除行

问题描述

我目前正在尝试从大型文本文件中删除大部分行并将所选信息重写为另一个。我必须逐行阅读原始文件,因为这些行出现的顺序是相关的。到目前为止,我能想到的最好的方法只提取相关行并使用以下内容重写它们:

with open('input.txt', 'r') as input_file:
    with open('output.txt', 'w') as output_file:

        # We only have to loop through the large file once
        for line in input_file:

            # Looping through my data many times is OK as it only contains ~100 elements
            for stuff in data:

                    # Search the line
                    line_data = re.search(r"(match group a)|(match group b)", line)

                    # Verify there is indeed a match to avoid raising an exception.
                    # I found using try/except was negligibly slower here
                    if line_data:
                        if line_data.group(1):
                            output_file.write('\n')

                        elif line_data.group(2) == stuff:
                            output_file.write('stuff')


        output_file.close()
    input_file.close()

然而,这个程序仍然需要大约 8 个小时才能运行一个大约 1Gb 的文件和大约 120,000 个匹配的行。我相信瓶颈可能涉及正则表达式或输出位,因为完成此脚本所需的时间与行匹配的数量成线性关系。

我曾尝试在将输出数据写入新文本文件之前先将其存储在内存中,但快速测试表明它存储数据的速度与之前写入数据的速度大致相同。

如果有帮助,我有 Ryzen 5 1500 和 8Gb 的 2133 Mhz RAM。但是,我的 RAM 使用量似乎永远不会用完。

标签: pythonregexpython-3.x

解决方案


您可以移动内部循环以仅在需要时运行。现在,您正在循环遍历data大文件中的每一行,但仅stuff在匹配时才使用变量。所以只需将for stuff in data:循环移动到if实际使用它的块内。

for line in input_file:
    # Search the line
    line_data = re.search(r"(match group a)|(match group b)", line)

    # Verify there is indeed a match to avoid raising an exception.
    # I found using try/except was negligibly slower here
    if line_data:
        for stuff in data:
            if line_data.group(1):
                output_file.write('\n')

            elif line_data.group(2) == stuff:
                output_file.write('stuff')

推荐阅读