【问题标题】:How can I write the lines from the first text file that are not present in the second text file?如何从第一个文本文件中写入第二个文本文件中不存在的行?
【发布时间】:2019-08-23 05:55:43
【问题描述】:

我想比较两个文本文件。第一个文本文件中的行不在第二个文本文件中。我想复制这些行并将它们写入一个新的 txt 文件。我想要一个 Python 脚本,因为我经常这样做,并且不想经常上网查找这些新行。我不需要确认 file2 中是否有 file1 中没有的内容。

我编写了一些似乎运行不一致的代码。我不确定自己做错了什么。

newLines = open("file1.txt", "r")
originalLines = open("file2.txt", "r")
output = open("output.txt", "w")

lines1 = newLines.readlines()
lines2 = originalLines.readlines()
newLines.close()
originalLines.close()

duplicate = False
for line in lines1:
    if line.isspace():
        continue
    for line2 in lines2:
        if line == line2:
            duplicate = True
            break

    if duplicate == False:
        output.write(line)
    else:
        duplicate = False

output.close()

对于file1.txt:

Man
Dog
Axe
Cat
Potato
Farmer

file2.txt:

Man
Dog
Axe
Cat

output.txt 应该是:

Potato
Farmer

但实际上是这样的:

Cat
Potato
Farmer

任何帮助将不胜感激!

【问题讨论】:

  • 如果您使用的是 Linux/Unix 操作系统,最好的命令(不是 Python)是comm -23 file1.txt file2.txt

标签: python file text readlines


【解决方案1】:

根据行为,file2.txt 不以换行符结尾,因此lines2 的内容为['Man\n', 'Dog\n', 'Axe\n', 'Cat']。请注意 'Cat' 缺少换行符。

我建议规范化你的行,使它们没有换行符,替换:

lines1 = newLines.readlines()
lines2 = originalLines.readlines()

与:

lines1 = [line.rstrip('\n') for line in newLines]
# Set comprehension makes lookup cheaper and dedupes
lines2 = {line.rstrip('\n') for line in originalLines}

和变化:

output.write(line)

到:

print(line, file=output)

这将为您添加换行符。确实,最好的解决方案是完全避免内部循环,改变所有这些:

for line2 in lines2:
    if line == line2:
        duplicate = True
        break

if duplicate == False:
    output.write(line)
else:
    duplicate = False

只是:

if line not in lines2:
    print(line, file=output)

如果您按照我的建议将set 用于lines2,那么无论file2.txt 的大小如何,测试成本都会从file2.txt 中的行数线性下降到大致恒定(只要这组独特的行完全可以放入内存中)。

更好的是,对打开的文件使用 with 语句,并流式传输 file1.txt 而不是将其保存在内存中,您最终会得到:

with open("file2.txt") as origlines:
    lines2 = {line.rstrip('\n') for line in origlines}

with open("file1.txt") as newlines, open("output.txt", "w") as output:
    for line in newlines:
        line = line.rstrip('\n')
        if not line.isspace() and line not in lines2:
            print(line, file=output)

【讨论】:

  • 更短的选择是lines1 = newLines.read().split('\n')
  • @JuanCarlos:虽然峰值内存成本更高(需要同时在内存中存储两个文件副本)。当文件以换行符结尾时,它还会导致空字符串(.splitlines() 将避免该问题)。就个人而言,我只是流式传输newLines,而根本没有将其存储到list
【解决方案2】:

您可以使用 numpy 获得更小更快的解决方案。 这里我们使用这些 numpy 方法 np.loadtxt 文档:https://docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html np.setdiff1d 文档:https://docs.scipy.org/doc/numpy-1.14.5/reference/generated/numpy.setdiff1d.html np.savetxt 文档:https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html

import numpy as np


arr=np.setdiff1d(np.loadtxt('file1.txt',dtype=str),np.loadtxt('file2.txt',dtype=str))
np.savetxt('output.txt',b,fmt='%s')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 2016-07-31
    相关资源
    最近更新 更多