Python遍历两个文件进行计算,然后输出三个文件

2 投票
4 回答
1807 浏览
提问于 2025-04-16 21:16

我有两个用制表符分隔的文件,举个例子:

文件1:

12  23  43  34
433  435  76  76

文件2:

123  324  53  65
12  457  54  32

我想要逐行比较这两个文件,看看文件1的每一行和文件2的每一行是否相同。比如说,如果文件1第一行的第一个数字和文件2第二行的第一个数字相同:

我想把文件1的这一行放到一个叫做输出的文件里。

然后,我还想把文件1中没有找到匹配的行放到一个新文件里,文件2中没有找到匹配的行也放到另一个新文件里。

到目前为止,我已经能找到匹配的行并把它们放到一个文件里,但我在把没有匹配的行放到两个单独的文件里时遇到了困难。

one=open(file1, 'r').readlines()
two=open(file2, 'r').readlines()
output=open('output.txt', 'w')
count=0
list1=[]    #list for lines in file1 that didn't find a match 
list2=[]    #list for lines in file2 that didn't find a match
for i in one:
    for j in two:
        columns1=i.strip().split('\t')
        num1=int(columns1[0])
        columns2=j.strip().split('\t')
        num2=int(columns2[0])
        if num1==num2:
           count+=1
           output.write(i+j)
        else:
           list1.append(i)        
           list2.append(j)

我在这里遇到的问题是关于else部分的。有没有人能告诉我更好的方法来做到这一点,我会非常感激。

编辑:感谢大家的快速回复!

我想要的三个输出文件是:

输出文件1:#两个文件之间的匹配结果

12 23 43 34 #来自文件1的行
12 457 54 32 #来自文件2的行

输出文件2:#来自第一个文件的没有找到匹配的行

433 435 76 76

输出文件3:#来自第二个文件的没有找到匹配的行

123 324 53 65

4 个回答

2

我建议你使用集合操作

from collections import defaultdict

def parse(filename):
    result = defaultdict(list)
    for line in open(filename):
        # take the first number and put it in result
        num = int(line.strip().split(' ')[0])
        result[num].append(line)  
    return result

def select(selected, items):
    result = []
    for s in selected:
        result.extend(items[s])
    return result

one = parse('one.txt')
two = parse('two.txt')
one_s = set(one)
two_s = set(two)
intersection = one_s & two_s
one_only = one_s - two_s
two_only = two_s - one_s

one_two = defaultdict(list)
for e in one: one_two[e].extend(one[e])
for e in two: one_two[e].extend(two[e])

open('intersection.txt', 'w').writelines(select(intersection, one_two))
open('one_only.txt', 'w').writelines(select(one_only, one))
open('two_only.txt', 'w').writelines(select(two_only, two))
2

我建议你使用csv模块来读取你的文件,可以这样做(你可能需要调整一些设置,具体可以参考这个链接):

import csv
one = csv.reader(open(file1, 'r'), dialect='excell')
two = csv.reader(open(file2, 'r'), dialect='excell')

然后,你可能会发现同时“压缩”两个文件的内容会更简单,可以这样做(具体可以参考这个链接):

import itertools
file_match = open('match', 'w')
file_nomatch1 = open('nomatch1', 'w')
file_nomatch2 = open('nomatch2', 'w')
for i,j in itertools.izip_longest(one, two, fillvalue="-"):
    if i[0] == j[0]:
        file_match.write(str(i)+'\n')
    else:
        file_nomatch1.write(str(i)+'\n')
        file_nomatch2.write(str(j)+'\n') 
        # and maybe handle the case where one is "-"

我重新看了一遍帖子,意识到你是想在两个文件中找到任意两行的匹配。也许有人会觉得上面的代码有用,但它并不能解决你具体的问题。

1

我觉得这不是最好的方法,但对我来说有效,而且看起来很容易理解:

# Sorry but was not able to check code below
def get_diff(fileObj1, fileObj2):
    f1Diff = []
    f2Diff = []
    outputData = []
    # x is one row
    f1Data = set(x.strip() for x in fileObj1)
    f2Data = set(x.strip() for x in fileObj2)
    f1Column1 = set(x.split('\t')[0] for x in f1Data)
    f2Column1 = set(x.split('\t')[0] for x in f2Data)
    l1Col1Diff = f1Column1 ^ f2Column1
    l2Col1Diff = f2Column1 ^ f1Column1
    commonPart = f1Column1 & f2column1
    for line in f1Data.union(f2Data):
        lineKey = line.split('\t')[0]
        if lineKey in common:
            outputData.append(line)
        elif lineKey in l1ColDiff:
            f1Diff.append(line)
        elif lineKey in l2ColDiff:
            f2Diff.append(line)
    return outputData, f1Diff, f2Diff

outputData, file1Missed, file2Missed = get_diff(open(file1, 'r'), open(file2, 'r'))

撰写回答