2014-04-04 63 views
3

我有一個看起來像這樣一個巨大的輸入文件打印相同的元素,查找和循環

c651 OS05T0-00 492 749 29.07 
c651 OS01T0-00 1141 1311 55.00 
c1638 MLOC_8.3  27 101 72.00 
c1638 MLOC_8.3  25 117 70.97 
c2135 TRIUR3_3-P1 124 210 89.66 
c2135 EMT17965 25 117 70.97 
c1914 OS02T0-00 2 109 80.56 
c1914 OS02T0-00 111 155 93.33 
c1914 OS08T0-00 528 617 50.00 

我想每個C內循環,看它是否有符合相同的元素[1]在2個獨立的文件打印

  1. ç包含相同的元素和
  2. 沒有相同的元素。

在c1914的情況下,由於有2個相同的元件和1不是,它進入到文件2。因此期望2個輸出文件將看起來像這樣,FILE1.TXT

c1638 MLOC_8.3  27 101 72.00 
c1638 MLOC_8.3  25 117 70.97 

file2的。 TXT

c651 OS05T0-00 492 749 29.07 
c651 OS01T0-00 1141 1311 55.00 
c2135 TRIUR3_3-P1 124 210 89.66 
c1914 OS02T0-00 2 109 80.56 
c1914 OS02T0-00 111 155 93.33 
c1914 OS08T0-00 528 617 50.00 

這是我試過,

oh1=open('result.txt','w') 
oh2=open('result2.txt','w') 
f=open('file.txt','r') 
lines=f.readlines() 
for line in lines: 
    new_list=line.split() 
    protein=new_list[1] 
    for i in range(1,len(protein)): 
     (p, c) = protein[i-1], protein[i] 
     if c == p: 
      new_list.append(protein) 
      oh1.write(line) 
     else: 
      oh2.write(line) 
+1

是什麼讓你「相當肯定它是完全錯誤的」?你有錯誤嗎(提供完整的追溯)?意想不到的產出(提供投入,預期和實際產出)?另外,請注意格式;你有一個缺少'''。 – jonrsharpe

+0

那麼,對於初學者,你還沒有定義'哦',這是你試圖寫入。那麼你能否更清楚地說明確定輸入文件中哪些文件應該運行的邏輯? – aepsil0n

回答

1

如果我理解正確的話,你要爲你的輸入文件具有第一元素txt1所有線路發送到您的第一個輸出文件,如果第二個元素所有這些線路的txt2是一樣的;否則所有這些行都會轉到第二個輸出文件。這是一個這樣的程序。

from collections import defaultdict 

# Read in file line-by-line for the first time 
# Build up dictionary of txt1 to set of txt2 s 
txt1totxt2 = defaultdict(set) 
f=open('file.txt','r') 
for line in f: 
    lst = line.split() 
    txt1=lst[0] 
    txt2=lst[1] 
    txt1totxt2[txt1].add(txt2); 

# The dictionary tells us whether the second text 
# is unique or not. If it's unique the set has 
# just one element; otherwise the set has > 1 elts. 
# Read in file for second time, sending each line 
# to the appropriate output file 
f.seek(0) 
oh1=open('result1.txt','w') 
oh2=open('result2.txt','w') 

for line in f: 
    lst = line.split() 
    txt1=lst[0] 
    if len(txt1totxt2[txt1]) == 1: 
     oh1.write(line) 
    else: 
     oh2.write(line) 

程序邏輯非常簡單。對於每個txt,它建立它所看到的txt2set。當你讀完文件時,如果該集只有一個元素,那麼你知道txt2是唯一的;如果該組具有多於一個的元素,則至少有兩個元素。請注意,這意味着如果在輸入文件中只有一個行與特定的txt1,它將始終被髮送到第一個輸出文件。如果這不是你想要的行爲,有很多方法可以解決這個問題。

請注意,由於文件很大,我一行一行地讀取它:lines=f.readlines()在原始程序中一次讀取整個文件到內存中。我已經通過了兩次:第二次輸出。如果這增加了運行時間,那麼您可以恢復lines=f.readlines()而不是第二次讀取它。但是,對於非常大的文件,程序應該更健壯。相反,如果你的文件確實非常大,那麼值得看看程序以進一步減少內存使用(字典txt1totxt2可以用更優化的東西替代,儘管如此更復雜,如果需要的話)。

編輯:關於此算法的內存成本的評論(現已刪除)有一個很好的觀點。詳細說來,內存使用率可能會很高,但另一方面它並不像存儲整個文件那麼嚴重:而是txt1totxt2是從每行的第一個文本到第二個文本的集合的字典,它是(唯一第一文本的大小)*(每個唯一第一文本的唯一第二文本的平均大小)的順序。這可能會比文件大小小很多,但這種方法可能需要進一步優化。這裏的方法是首先進行一些簡單的操作 - 如果有必要,可以迭代進行優化。

1

嘗試......

import collections 

parsed_data = collections.OrderedDict() 

with open("input.txt", "r") as fd: 
    for line in fd.readlines(): 
     line_data = line.split() 
     key = line_data[0] 
     key2 = line_data[1] 
     if not parsed_data.has_key(key): 
      parsed_data[key] = collections.OrderedDict() 
     if not parsed_data[key].has_key(key2): 
      parsed_data[key][key2] = [line] 
     else: 
      parsed_data[key][key2].append(line) 

# now process the parsed data and write result files 
fsimilar = open("similar.txt", "w") 
fdifferent = open("different.txt", "w") 

for key in parsed_data: 
    if len(parsed_data[key]) == 1: 
     f = fsimilar 
    else: 
     f = fdifferent 
    for key2 in parsed_data[key]: 
     for line in parsed_data[key][key2]: 
      f.write(line) 
fsimilar.close() 
fdifferent.close() 

希望這有助於

+0

有沒有辦法取代集合模塊?我認爲我使用的版本不支持這個模塊,因爲我沒有加入根,我無法更新或下載任何東西.. – user3224522

+1

如果你不關心的順序項目列在結果文件中,然後你可以用'dict()'替換每個'collections.OrderedDict()'' –