2014-10-06 58 views
1

您好我寫了一個簡單的代碼在Python中做到以下幾點:獲得不匹配的行號蟒蛇

我有兩個文件總結基因組數據。第一個文件有我想擺脫的位點的名字,它看起來像這樣

File_1:

R000002 
R000003 
R000006 

第二個文件有我所有位點的名稱和位置,看起來像這樣:

File_2:

R000001 1 
R000001 2 
R000001 3 
R000002 10 
R000002 2 
R000002 3 
R000003 20 
R000003 3 
R000004 1 
R000004 20 
R000004 4 
R000005 2 
R000005 3 
R000006 10 
R000006 11 
R000006 123 

我希望做的是讓所有的文件2位點的相應行號不在文件1,所以最終的結果應該是這樣的:

結果:

1 
2 
3 
9 
10 
11 
12 
13 

我寫了下面簡單的代碼,它可以完成

#!/usr/bin/env python 

import sys 

File1 = sys.argv[1] 
File2 = sys.argv[2] 

F1 = open(File1).readlines() 
F2 = open(File2).readlines() 
F3 = open(File2 + '.np', 'w') 
Loci = [] 

for line in F1: 
     Loci.append(line.strip()) 

for x, y in enumerate(F2): 
     y2 = y.strip().split() 
     if y2[0] not in Loci: 
       F3.write(str(x+1) + '\n') 

然而,當我在我的真實數據集運行作業本,其中的第一個文件有58470行第二個文件有12881010行,它似乎需要永遠。我猜測的瓶頸是在代碼中有貫穿整個File_2反覆搜索

if y2[0] not in Loci: 

一部分,但我一直沒能找到一個更快的解決方案。

任何人能幫助我,並顯示處事更Python的方式。

在此先感謝

+0

是你訂購的文件嗎? – 2014-10-06 04:24:31

+0

是的,他們都訂購。但是,只有File2中的一些軌跡位於File_1中,並且File1不會順序執行。在File_1中可以從R000123跳轉到R000255。 – iksaglam 2014-10-06 04:26:21

+0

對於初學者,您可以將'Loci'變成'set'而不是'list'。這肯定會改善查找時間。 – sberry 2014-10-06 04:30:56

回答

2

這裏是如果你的文件是有序的,不關心一些稍微更Python代碼。我寧願打印所有文件並將其重定向到文件./myscript.py > outfile.txt,但您也可以傳入另一個文件名並寫入該文件。

#!/usr/bin/env python 
import sys 

ignore_f = sys.argv[1] 
loci_f = sys.argv[2] 

with open(ignore_f) as f: 
    ignore = set(x.strip() for x in f) 

with open(loci_f) as f: 
    for n, line in enumerate(f, start=1): 
     if line.split()[0] not in ignore: 
      print n 

在列表中搜索某事物是O(n),而對於一個集合只需要O(1)。如果訂單無關緊要並且您擁有獨特的商品,請在列表上使用set。雖然這不是最佳的,但它應該是O(n)而不是O(n × m),就像您的代碼一樣。

你還沒有關閉您的文件,從讀書的時候是不是什麼大不了的事,但寫它是什麼時候。我使用上下文管理器(with),所以Python爲我做。

風格的角度來看,使用描述性的變量名。並避免UpperCase名稱,這些名稱通常用於類別(請參閱PEP-8)。

如果你的文件是有序的,你可以通過他們一步在一起,無視線,其中軌跡名稱是相同的,那麼當它們的不同,採取另一個步驟在您忽略文件,並重新檢查。

0

要爲比賽的更高效的搜索,你可以簡單地使用set代替list

Loci = set() 

for line in F1: 
    Loci.add(line.strip()) 

其餘部分應該工作一樣,但速度更快。

更高效的是以一種鎖步方式走下文件,因爲它們都是排序的,但這需要更多的代碼,而且可能不是必需的。