2015-09-16 111 views
5

我有一系列的輸入文件,如:分割線從INFILE在python

chr1 hg19_refFlat exon 44160380 44160565 0.000000 + . gene_id "KDM4A"; transcript_id "KDM4A"; 
chr1 hg19_refFlat exon 19563636 19563732 0.000000 - . gene_id "EMC1"; transcript_id "EMC1"; 
chr1 hg19_refFlat exon 52870219 52870551 0.000000 + . gene_id "PRPF38A"; transcript_id "PRPF38A"; 
chr1 hg19_refFlat exon 53373540 53373626 0.000000 - . gene_id "ECHDC2"; transcript_id "ECHDC2_dup2"; 
chr1 hg19_refFlat exon 11839859 11840067 0.000000 + . gene_id "C1orf167"; transcript_id "C1orf167"; 
chr1 hg19_refFlat exon 29037032 29037154 0.000000 + . gene_id "GMEB1"; transcript_id "GMEB1"; 
chr1 hg19_refFlat exon 103356007 103356060 0.000000 - . gene_id "COL11A1"; transcript_id "COL11A1"; 

在我的代碼,我試圖捕捉每行2個元素,第一個是後該號碼它說,外顯子,二是基因(該數字和字母組合的「包圍」,如「KDM4A」這裏是我的代碼:

with open(infile,'r') as r: 
     start = set([line.strip().split()[3] for line in r]) 
     genes = set([line.split('"')[1] for line in r]) 
     print len(start) 
     print len(genes) 

出於某種原因開始工作正常,但基因是不是拍攝什麼。這裏是輸出:

48050 
0 

我想,這是什麼做的「」周圍的基因的名字,但如果我進入這個在終端上正常工作:

>>> x = 'A b P "G" m' 
>>> x 
'A b P "G" m' 
>>> x.split('"')[1] 
'G' 
>>> 

任何解決方案將不勝感激?如果即使它是一種完全不同的方式來捕獲每行的2項數據。由於

回答

8

那是因爲你的文件對象被耗盡,當你遍歷一次在這裏start = set([line.strip().split()[3] for line in r])一次你在疲憊的文件對象試圖循環這裏genes = set([line.split('"')[1] for line in r])

解決方案:

您可以尋求該文件的開始(這是解決方案之一)

修改代碼:

with open(infile,'r') as r: 
    start = set([line.strip().split()[3] for line in r]) 
    r.seek(0, 0) 
    genes = set([line.split('"')[1] for line in r]) 
    print len(start) 
    print len(genes) 
+0

好了,所以我應該在OP做些什麼呢? – Kevin

+0

@Kevin編輯感謝 – The6thSense

+0

謝謝,我之前沒有遇到過這個seek方法,非常有用。我接受這個答案,因爲它的最短最簡潔,並解決了1短代碼 – user3062260

4

您可以使用正則表達式。

with open(file) as f: 
    start = [] 
    genes = [] 
    for line in f: 
     st, gen = re.search(r'\bexon\s+(\d+)\b.*?\s+gene_id\s+"([^"]*)"', line).groups() 
     start.append(st) 
     genes.append(gen) 
    print set(start) 
    print set(genes) 

DEMO

+0

現在你有兩個問題! –

+0

但是'start'和'genes'現在不是字符串而是集合嗎?看起來與OP最初有什麼不同。 – Kevin

+0

@Kevin好趕上..現在沒關係,我認爲.. –

2

您可以將所有的行加載到一個列表,然後在該列表中的每個項目執行split

with open(infile) as r: 
    lines = [line for line in r] 
    start = set([line.strip().split()[3] for line in lines]) 
    genes = set([line.split('"')[1] for line in lines]) 
(不知道是如果文件是長的效率有多高)
+0

我曾想過這件事,但該文件是巨大的,我需要循環通過24個類似大小的文件,所以這將需要年齡。 – user3062260

2

使用shlex(因爲它就像外殼參數),可以中和多個空格和引用
不確定它是否更快,但安全且有點不錯

import shlex 
with open(infile, 'r') as f: 
    for line in f: 
     parts = shlex.split(line.replace(';', '')) 
     print parts[3], parts[9] 
+0

我之前沒有遇到shlex,它似乎很好地解決了這個問題。重置循環似乎是最簡單的解決方案。 – user3062260

2

無法加載genes的原因是您需要重新從頭開始讀取文件。下面的方法雖然應該工作:

import re 

start = set() 
genes = set() 

with open('input.txt', 'r') as f_input: 
    for line in f_input: 
     s, g = re.match(r'(?:.*?\s+){3}(\d+).*"(\w+)"', line).groups() 
     start.add(s) 
     genes.add(g) 

print start 
print genes 

給你的輸出:

set(['44160380', '29037032', '103356007', '19563636', '53373540', '52870219', '11839859']) 
set(['COL11A1', 'PRPF38A', 'KDM4A', 'C1orf167', 'EMC1', 'GMEB1', 'ECHDC2_dup2'])