2015-06-28 34 views
1

我有一個包含此信息的文件:我想創建一個字典,其中NM_的是鍵和開始和結束都是通過定義一個函數創建的文件字典

#chrom start end isoform 
chr1 75 90 NM_100 
chr1 100 120 NM_100 
chr2 25 50 NM_200 
chr2 55 75 NM_200 
chr2 100 125 NM_200 
chr2 155 200 NM_200 

從這個文件價值。像這樣:

dictionary = {NM_100: [(75, 90), (100,120)], NM_200: [(25, 50), (55,75), (100, 125), (155, 200)]} 

我一直在嘗試使用此代碼生成功能,讓我拉上的開始和結束,但我似乎無法得到它的正常工作。

def read_exons(line): 
    parts = iter(line.split()) 
    chrom = next(parts) 
    start = next(parts) 
    end = next(parts) 
    isoform = next(parts) 
    return isoform, [(s, e) for s, e in zip(start, end)] 

with open('test_coding.txt') as f: 
    exons = dict(read_exons(line) for line in f 
     if not line.strip().startswith('#')) 

據我所知,功能不會讓我追加到值,但我在努力弄清楚如何連得開始和結束一行在字典中正確顯示。有任何想法嗎? iter()zip有問題嗎?

回答

1

collections.defaultdict可能幫助:

import collections 

exons = collections.defaultdict(list) 
for line in f: 
    chrom, start, end, isoform = line.split() 
    exons[isoform].append((int(start), int(end))) 

簡單!


它利用了幾件事情:

  • 它使用元組拆包解包線列,而不是iter()解決方案,您有以上。通常,元組拆包更簡單,更易於閱讀。
  • 它逐漸建立字典,而不是試圖一次性完成所有這些,因爲你當前的解決方案嘗試了(注意,如果你一行一行地處理數據,你不能一次收集所有的開始/結束對!)
  • 它使用collections.defaultdict有效地使每個鍵映射到一個空列表(最初),這使您無需檢查每個鍵是否映射。沒有defaultdict,你會做

    exons = {} 
    ... 
        if isoform not in exons: 
         exons[isoform] = [] 
        exons[isoform].append(...) 
    
+0

真棒!我試圖使用這種技術,但它給了我一個錯誤:'ValueError:對於int()以10爲底的無效文字:'開始' – interstellar

+0

從頭開始。我得到它的工作!謝謝!這麼簡單:) – interstellar