Python中写了一个读取两个文件并比较第一行的脚本,但结果总是不对劲,哪里出错了?

使用场景: 以其中一个文件为基准(正确的值),对比两个文件中不同的行,并统计出来正确的数,错误的数 如

1.txt (基准文件)
a.jpg 0
b.jpg 2
c.jpg 3
...
2.txt
a.jpg 1
b.jpg 2
c.jpg 3
...

那么这两个文件中就 a.jpg 出错了 我的思路比较粗爆,就是拿 1 这个基准的每一行去了空格后,与 2 里边比,比中就记个数,一直把 1 中的挨个与 2 中的比一遍,但我发现这样写,每次 都要重新打开文件 2 一次,而且感觉不也靠谱,而且不知道怎么把错误的给挑出来,有什么更好的办法吗?或者是优化一下我这个

def compare(testfile, basefile):
    correct = 0
    all = 0
    with open(testfile, encoding="utf-8") as f1:
        for i in f1.readlines():
            all += 1
            with open(basefile, encoding="utf-8") as f2:
                for j in f2.readlines():
                    if i.replace(" ", "") == j.replace(" ", ""):
                        correct += 1
                    else:#想把错误的输出出来,但没有输出
                        print(i)#想把错误的输出出来
    print("样本数: %d\n 正确数: %d\n 错误数: %d\n 准确率: %f" %
          (all, correct, all - correct, correct / all))

if name == ‘main’: compare(“test1.txt”, “base1.txt”)


Python中写了一个读取两个文件并比较第一行的脚本,但结果总是不对劲,哪里出错了?

13 回复

在循环里别用 with 呗,直接读文件读完关掉


你遇到的问题很可能是文件编码或者换行符导致的。让我看看代码才能确定。

import sys

def compare_first_lines(file1_path, file2_path):
    """比较两个文件的第一行内容"""
    try:
        with open(file1_path, 'r', encoding='utf-8') as f1, \
             open(file2_path, 'r', encoding='utf-8') as f2:
            
            # 读取第一行并去除可能的换行符
            line1 = f1.readline().rstrip('\n')
            line2 = f2.readline().rstrip('\n')
            
            # 打印调试信息
            print(f"文件1第一行: {repr(line1)}")
            print(f"文件2第一行: {repr(line2)}")
            print(f"长度比较: {len(line1)} vs {len(line2)}")
            
            # 比较内容
            if line1 == line2:
                print("第一行内容相同")
                return True
            else:
                print("第一行内容不同")
                # 找出差异位置
                for i, (c1, c2) in enumerate(zip(line1, line2)):
                    if c1 != c2:
                        print(f"第{i}个字符不同: '{c1}' (ASCII: {ord(c1)}) vs '{c2}' (ASCII: {ord(c2)})")
                        break
                if len(line1) != len(line2):
                    print(f"长度不同: {len(line1)} vs {len(line2)}")
                return False
                
    except FileNotFoundError as e:
        print(f"文件未找到: {e}")
        return False
    except UnicodeDecodeError:
        print("编码错误,尝试其他编码...")
        # 尝试常见编码
        encodings = ['utf-8-sig', 'gbk', 'latin-1']
        for encoding in encodings:
            try:
                with open(file1_path, 'r', encoding=encoding) as f1, \
                     open(file2_path, 'r', encoding=encoding) as f2:
                    line1 = f1.readline().rstrip('\n')
                    line2 = f2.readline().rstrip('\n')
                    print(f"使用{encoding}编码:")
                    print(f"文件1: {repr(line1)}")
                    print(f"文件2: {repr(line2)}")
                    break
            except:
                continue

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("用法: python script.py <文件1> <文件2>")
    else:
        compare_first_lines(sys.argv[1], sys.argv[2])

常见问题:

  1. 编码问题:Windows记事本保存的UTF-8带BOM文件,用utf-8-sig编码
  2. 换行符差异:Windows是\r\n,Linux是\n,用rstrip('\n')处理
  3. 不可见字符:空格、制表符、全角半角字符
  4. 文件路径:相对路径和绝对路径问题

用这个脚本跑一下,看repr()输出的原始内容对比。

建议:用repr()打印原始内容对比。

没必要非得用 with。

读到 numpy 或者 pandas,然后直接比对列值,很简单呀

return len(set(line.strip() for line in open(testfile)) - set(line.strip() for line in open(basefile)))

你实际上是同行数比较吧?
这样只需要一个 for 行数 就够了

你现在是两文件每行都交叉比较,数量级是相乘

数据量不大可以直接 set 了,再取交集吧

不是同行,是要交叉,可能 我举的例子看上去每一行都一样,其实不是这样的,是乱序的

分别打开前一个个文件,用前面的“ a.jpg ”、“ b.jpg ”…当作 key 后面的当作值存入字典,再打开第二个文件,逐行读入,用前一段去字典里取值,与后面的对比。

小文件可以这样搞,大点的文件借助一下 redis 啥的(或者直接比较 hash 值)

小文件指的是多小?

内存不爆我觉得都小。。。

那应该没啥压力,哈哈

回到顶部