2014-11-23 70 views
0

今晚我從兩個文件創建文件時遇到問題。我想要實現的文本文件將包含來自第一個文件的3個第一列和來自第二個文件的兩個2列。到目前爲止,我已經爲這些文件做了很好的閱讀和連接,但最終我並沒有實現所有的連接,只是一個連接正確。 :(管理兩個文件中的嵌套循環PYTHON

文件已結構介紹如下: 文件1:

DATA1 DATA2 data3 ...... 
DATA1 DATA2 data3 ...... 

文件2:

DATA1 DATA2 data3' data4 .... 
DATA1 DATA2 data3' data4 .... 

OUTPUTFILE:

DATA1 DATA2 data3 data3' data4 
DATA1 DATA2 data3 data3' data4 

正如我所說的,現在我只取得了一排在正確的方式不是每個。文件1和文件2沒有得到相同數量的r OWS。兩個輸入文件中的DATA1和DATA2必須相同。 問題是某處的循環,因爲我不能acheive完整的文件:( 我會版本的我的代碼錯誤校正非常gratefull

file1 = open('file1.txt', 'r') 
file2 = open('file2.txt', 'r') 
finalfile = None 
for line in file1: 
    row1 = line.rstrip().split() 
    first_column1 = row1[0] 
    second_column1 = row1[1] 
    #print(str(first_two_columns1)+ " "+ str(first_three_columns1)+ "\n") 
    for line in file2: 
     row2 = line.rstrip().split() 
     first_column2 = row2[0] 
     second_column2 = row2[1] 
     #print(str(first_two_columns1)+ " "+ str(first_two_columns2)+ "\n") 
     if(float(first_column1) == float(first_column2)) and (second_column1 == second_column2): 
      rows = row1[0] + " " + row1[1] + " " + row1[2] + " " + row2[2] + " " + row2[3] + "\n" 
      final_filename = 'final_file_{}.txt'.format(row1[0]) 
      finalfile = open(final_filename, "w") 
     finalfile.write(rows) 
if finalfile: 
    finalfile.close() 
file1.close() 
file2.close() 
+0

輸出文件是否需要保持與任一輸入文件相同的順序?這些文件有多大? – wwii 2014-11-23 18:27:44

+0

沒有順序並不重要,這個文件每個最多有70行:) – Mikul 2014-11-23 18:51:33

+0

'file1'總會比'file2'長嗎? – wwii 2014-11-23 19:10:29

回答

0

如果這兩個文件和輸出文件具有相同數量的行和任務是合併每個相應的對線形成輸入文件,以使輸出文件的每一行,那麼你不想嵌套的循環:

for line in file1: 
    row1 = line.strip().split() 
    line = file2.readline() 
    row2 = line.strip().split() 
    ... 

從那裏,你建立你的輸出線。

更新:如果輸入文件不匹配,那麼您需要從file1的每一行開始讀取file2,您可以通過打開/處理/關閉每行的file1,或使用lseek回到開頭。如果file2不是太大,可以將其內容讀入字典中,以便只讀一次。

+0

thx但他們沒有得到相同的:(這就是爲什麼我檢查每個文件的第一和第二列 – Mikul 2014-11-23 17:47:42

0

我沒有試圖找到你的代碼出錯的地方。

首先讓我們從每個文件的排序行開始。有時,對數據進行預先排序可以讓事情更輕鬆。

import csv, operator 
# key is a callable that returns 
# the first two items in a sequence 
key = operator.itemgetter(0,1) 

# get a sorted list of rows for each file 
with open('file1.csv') as one, open('file2.csv') as two: 
    reader = csv.reader(one) 
    file_one = sorted(reader, key = key) 
    #one = sorted(csv.reader(one), key = key) 
    reader = csv.reader(two) 
    file_two = sorted(reader, key = key) 
    #two = sorted(csv.reader(two), key = key) 

這是假設有可能不匹配,你會需要遍歷file2file1每一行。我已經包含了一些內嵌評論。這不需要預先排序的數據,但仍然可以使用它。

with open ('out.csv', 'w') as out: 
    writer = csv.writer(out) 
    for line1 in file_one: 
     # find the line in file2 that matches 
     for line2 in file_two: 
      if line1[:2] == line2[:2]: 
       # write the new line to the new file 
       out_line = line1[:3] + line2[2:4] 
       writer.writerow(out_line) 
       #stop looking in file2 
       break 

如果你能保證總是有一個匹配的file2然後你只需要進行一次穿過每個文件。發生器方便地跟蹤迭代的迭代。這需要上面定義的每個文件的排序列表。

# generator function 
def lines(iterable): 
    '''yields succesive items from iterable. 
    ''' 
    for item in iterable: 
     yield item 

with open ('out.csv', 'w') as out: 
    writer = csv.writer(out) 
    file_one = lines(file_two) 
    for line2 in file_two: 
     # find the line in file2 that matches 
     try: 
      line1 = file_one.next() 
      while line1[:2] != line2[:2]: 
       line1 = file_one.next() 
     except StopIteration: 
      # no matching lines in file 2 
      error_text = 'file2 does not have a matching line for ' + line1 
      raise ValueError(error_text) 
     out_line = line1[:3] + line2[2:4] 
     writer.writerow(out_line)