使用Python对比行数不同的CSV文件:匹配结果仅输出一项问题排查
问题分析与修复方案
你遇到的问题根源很简单:csv.reader对象是一次性的迭代器。当你第一次遍历完reader2之后,它就已经走到文件末尾了,后续外层循环的line1再去遍历reader2时,已经没有任何数据可以迭代,所以只能输出第一个匹配的结果。
另外还要注意你代码里的一个逻辑问题:你写的条件是or,但你的需求是“att1和att2内容相同时”,也就是one.csv的att1等于two.csv的att1(对应line1[1] == line2[2]),同时one.csv的att2等于two.csv的att2(对应line1[2] == line2[1]),所以应该用and而不是or,否则会匹配到只满足单个条件的记录,不符合你的需求。
下面给你两种修复方案:
方案1:每次循环重新读取第二个文件
这种方法最简单,适合小文件场景:
import csv path1 ="/home/vishver/Desktop/" count = 0 # 遍历第一个文件的每一行 for line1 in csv.reader(open(path1 + "one.csv", "r")): # 每次循环都重新打开并读取第二个文件,重置迭代器 for line2 in csv.reader(open(path1 + "two.csv", "r")): # 修正条件为and,匹配att1和att2都相同的情况 if line1[1] == line2[2] and line1[2] == line2[1]: result = (line2[0], line1[0], line1[1], line1[2]) print(result) count += 1 print(count)
方案2:预加载第二个文件到内存(推荐)
如果你的文件比较大,重复读取会有IO开销,推荐先把第二个文件的所有数据加载到内存列表中,后续循环直接遍历内存数据,效率更高:
import csv path1 ="/home/vishver/Desktop/" # 先读取第二个文件的所有数据到内存 with open(path1 + "two.csv", "r") as f2: two_records = list(csv.reader(f2)) count = 0 # 使用with语句自动管理文件关闭,避免资源泄漏 with open(path1 + "one.csv", "r") as f1: reader1 = csv.reader(f1) for line1 in reader1: # 遍历预加载的内存数据,每次都是从头开始 for line2 in two_records: if line1[1] == line2[2] and line1[2] == line2[1]: result = (line2[0], line1[0], line1[1], line1[2]) print(result) count += 1 print(count)
额外提示:尽量使用with语句打开文件,它会在代码块结束后自动关闭文件,比直接open后手动关闭更安全,也更简洁。
内容的提问来源于stack exchange,提问作者vishu
相关产品推荐
相关产品推荐

