2016-12-22 13 views
3

ファイルからマルチレベル辞書を作成しようとしています。Pythonを使用してファイルからマルチレベル辞書を作成する方法

ファイル形式は怒鳴るようなものです:file.txtは

name1 gene1 cds  1  2  + 
name1 gene1 cds  2  5  - 
name1 gene1 exon 1  2  + 
name1 gene1 exon 2  5  - 
name1 gene2 cds  4  6  + 
name1 gene2 cds  6  9  + 
name1 gene2 exon 1  10  + 
name1 gene2 exon 2  5  - 
name2 gene1 gene 1000 1333 + 

辞書データ構造は怒鳴るようなものです。

dct = { 'name1' : {'gene1':{'cds':[[1, 2, '+'],[2, 5, '-']], "exon": [[1, 2, '+'],[2, 5, '-']] } , 'gene2':{'cds':[[4, 6, '+'],[6, 9, '+']], "exon": [[1, 10, '+'],[2, 5, '-']] } } } 

または単に理解のために:

name1 
     gene1 
       exon 
         1, 2, "+", 
         2, 5, "-" 
       CDS 
         1, 2, "+" 
         2, 5, "-" 
     gene2 
       CDS 
         4, 6 "+" 
         6, 9, "+" 
       exon 
         1, 10, "+", 
         2, 5, "-" 
name2 
... 
... 

私の試み:

dct[tmp[0]][tmp[1]][tmp2]=[tmp[3], tmp[4], tmp[5]] 

この

に助けが必要です:辞書の作成中に、私は問題を取得しています

import re 

def read_dct(name): 
     filename = name 
     dct = {} 
     ReadFH = open(filename, 'r') 
     for i, line in enumerate(ReadFH): 
       line = line.rstrip() 
       tmp=re.split(r'\t', line) 
       if(len(tmp) > 5): 
         dct[tmp[0]][tmp[1]][tmp2]=[tmp[3], tmp[4], tmp[5]] 

     ReadFH.close 
     return dct 

filename = "file.txt" 
dct = read_dct(filename) 
print dct 

0あなたが使用することができます

+0

は、各 'exon'または' CDS'は3つの事の2セットを持っていることが保証されますか? – Arc676

+0

いいえ、彼らは**複数のセット**との誤差を修正した後、それはあなたと同じだっただろうので、私の答えを削除した – Arijit

答えて

2

第3レベルの値がリストされているdefaultdictネストされた:

from collections import defaultdict 

res = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 

with open('test.txt') as f: 
    for line in f: 
     k1, k2, k3, *val = line.split() 
     res[k1][k2][k3].append(val) 

for k, v in res.items(): 
    for k2, v2 in v.items(): 
     for k3, v3 in v2.items(): 
      print('{}, {}, {}: {}'.format(k, k2, k3, v3)) 

出力:extended iterable unpackingは、Python 2でPython 2ではサポートされていないためだけのPython 3で動作します

name2, gene1, gene: [['1000', '1333', '+']] 
name1, gene2, cds: [['4', '6', '+'], ['6', '9', '+']] 
name1, gene2, exon: [['1', '10', '+'], ['2', '5', '-'] 
name1, gene1, cds: [['1', '2', '+'], ['2', '5', '-']] 
name1, gene1, exon: [['1', '2', '+'], ['2', '5', '-']] 

以上splitによって返されたlistを保存し、スライスを使用してキー&の値を取得することができます。

with open('test.txt') as f: 
    for line in f: 
     l = line.split() 
     k1, k2, k3 = l[:3] 
     res[k1][k2][k3].append(l[3:]) 
+1

3つの事を有することができます。ただし、[PEP about extended unpacking](https://www.python.org/dev/peps/pep-3132/)にリンクを追加することもできます。 –

+0

@tobias_kリンクをありがとう、答えに追加されました。 – niemmi

+1

また、 "Above only works ..."を "this and this only works ..."に変更することをお勧めします。これは、残りのアプローチ、特にネストされた 'defaultdict'がPython 2でもうまく動作するためです。代わりに 'k1、k2、k3、k4、k5、k6 = ...'を使うか、アンパックを全くしないでください。 –

関連する問題