Цикл Python через два файла, выполнить вычисления, а затем вывести 3 файла - PullRequest
2 голосов
/ 11 июля 2011

У меня есть 2 файла с разделителями табуляции например:

file1:

12  23  43  34
433  435  76  76

file2:

123  324  53  65
12  457  54  32

Я бы хотел просмотреть эти 2 файла, сравнивая каждую строку файла file1 с файлом file2 и наоборот. Например, если 1-й номер 1-й строки в файле 1 совпадает с 1-м номером 2-й строки в файле 2: Я хотел бы поместить с 1-й строки в file1 в файл с именем output. тогда я хотел бы поместить все строки из file1, которые не нашли соответствия в файле 2, в новый файл и все строки из file2, которые не нашли соответствия в file1 в новом файле.

На данный момент мне удалось найти совпадающие строки и поместить их в файл, но у меня возникли проблемы с размещением не совпадающих строк в 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)

Проблема, с которой я столкнулся, связана с остальной частью. Может кто-нибудь показать мне правильный и лучший способ сделать это, я был бы очень признателен.

РЕДАКТИРОВАТЬ: Спасибо за быстрый ответ всем 3 выхода, которые я бы искал:

Output_file1: # Сопоставление результатов между двумя файлами

12 23 43 34 # строка из файла1
12 457 54 32 # строка из файла2

Output_file2: # строк из первого файла, который не нашел соответствия

433 435 76 76

Output_file3: # строки из второго файла, которые не нашли совпадений

123 324 53 65

Ответы [ 4 ]

2 голосов
/ 11 июля 2011

Я бы предложил использовать операция установки

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 голосов
/ 11 июля 2011

Я бы посоветовал вам использовать модуль csv для чтения ваших файлов следующим образом (возможно, вам придется возиться с диалектом, см. http://docs.python.org/library/csv.html для справки:

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

тогда вам, возможно, будет проще "заархивировать" вдоль строк обоих файлов одновременно, как показано ниже (см. http://docs.python.org/library/itertools.html#itertools.izip_longest):

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 голос
/ 11 июля 2011

Думаю, что это не лучший способ, но он работает для меня и выглядит довольно легко для понимания:

# 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'))
1 голос
/ 11 июля 2011

Я думаю, что этот код соответствует вашим целям

one=open(file1, 'r').readlines()
two=open(file2, 'r').readlines()
output=open('output.txt', 'w')

first = {x.split('\t')[0] for x in one}
second = {x.split('\t')[0] for x in two}
common = first.intersection( second )
list1 = filter( lambda x: not x.split('\t')[0] in common, one )
list2 = filter( lambda x: not x.split('\t')[0] in common, two )
res1 = filter( lambda x: x.split('\t')[0] in common, one )
res2 = filter( lambda x: x.split('\t')[0] in common, two )
count = len( res1 )
for x in range(count):
    output.write( res1[x] )
    output.write( res2[x] )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...