2016-04-25 16 views
1

に辞書を入れ子になった:プリントは、私は次のdictを持つTSV形式のファイル

{'A1137': {'Called': 10, 'hom_alt': 10, 'private_hom': 8}, 
'A2160': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
'A2579': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
'A2594': {'Called': 9, 'hom_alt': 1, 'hom_ref': 8}} 

私は出力がある希望:

stats A1137 A2160 A2579 A2594 
Called 10 10 10 9 
hom_alt 10 1 1 1 
hom_ref 0 9 9 8 
private_hom 8 0 0 0 

任意のサブセットは、 'カウンター' を逃した場合、観察されるように、ゼロはその場所を取るべきです。 私はそれを行うためにさまざまな方法を試しましたが、私はそれを達成できません。私はではなく、ネストされたものとの単純な辞書で印刷を行うことができるよ:

with open(res, 'w') as csvfile: 
    w = csv.writer(csvfile, delimiter='\t') 
    w.writerow(['#Global Statistics:']) 
    for key, value in d.items(): 
     w.writerow([key, value]) 
    w.writerow(['\n']) 
return res 
+0

あなたはアップフロントネストされた辞書内のすべての可能なキーを知っているか、それはそれらのキーから自動検出する必要がありますか? –

+0

この場合、 "A1137 A2160 A2579 A2594"を参照してくださいか? – cucurbit

+0

いいえ、 'Called'、' hom_alt'、 'hom_ref'、' private_hom'です。 –

答えて

1

これは、あなたが行ごとの辞書に渡すcsv.DictWriter()を、使用して簡単です。

辞書に含まれているすべての辞書の組み合わせを作成することで、辞書内のキーを自動検出することができます(キーが引き出されます)。これらは、あなたの出力にstats値は次のとおりです。

fields = sorted(d) 
stats = sorted(set().union(*d.values())) # use d.itervalues() in Python 2 

with open(res, 'w') as csvfile: 
    w = csv.DictWriter(csvfile, delimiter='\t', fieldnames=['stats'] + fields) 
    w.writerow({'stats': '#Global Statistics:'}) 
    w.writeheader() 
    for stat in stats: 
     # produce a dictionary mapping field name to specific statistic for 
     # this row 
     row = {k: v.get(stat, 0) for k, v in d.items()} 
     row['stats'] = stat 
     w.writerow(row) 

デモ:

>>> import csv 
>>> import sys 
>>> d = {'A1137': {'Called': 10, 'hom_alt': 10, 'private_hom': 8}, 
...  'A2160': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
...  'A2579': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
...  'A2594': {'Called': 9, 'hom_alt': 1, 'hom_ref': 8}} 
>>> fields = sorted(d) 
>>> stats = sorted(set().union(*d.values())) 
>>> w = csv.DictWriter(sys.stdout, delimiter='\t', fieldnames=['stats'] + fields) 
>>> w.writerow({'stats': '#Global Statistics:'}) 
#Global Statistics: 
>>> w.writeheader() 
stats A1137 A2160 A2579 A2594 
>>> for stat in stats: 
...  # produce a dictionary mapping field name to specific statistic for 
...  # this row 
...  row = {k: v.get(stat, 0) for k, v in d.items()} 
...  row['stats'] = stat 
...  w.writerow(row) 
... 
Called 10  10  10  9 
hom_alt 10  1  1  1 
hom_ref 0  9  9  8 
private_hom  8  0  0  0 
+0

ありがとう@Martijn。私は疑問を持っていました.Dictの "秩序を守る"ことは可能でしょうか?つまり、A1137、A2160、A2579、A2594はソートされていますが、A1137はA3137という名前であると考えていますので、A3137、A2160、A2579、A2594のキーがあります。この順序で出力テーブルを持つことは可能ですか? – cucurbit

+0

@cucurbit:いいえ、辞書には注文がないためです。それらは順序付けられていない構造です。 「Pythonの辞書やセットの順序が恣意的なのはなぜですか?」(https://stackoverflow.com/a/15479974)を参照してください。 –

1
from collections import defaultdict 

data = { 
'A1137': {'Called': 10, 'hom_alt': 10, 'private_hom': 8}, 
'A2160': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
'A2579': {'Called': 10, 'hom_alt': 1, 'hom_ref': 9}, 
'A2594': {'Called': 9, 'hom_alt': 1, 'hom_ref': 8} 
} 

fields = "stats","Called","hom_alt","hom_ref","private_hom" 

newdata = list() 
for (k,v) in data.items(): 
    d = defaultdict(int) 
    d.update(v) 
    d["stats"] = k 
    newdata.append(d) 

table = [fields] 
for d in newdata: 
    table.append([d[f] for f in fields]) 

#first, a pretty print 
fmt = "{:<11}" + "{:>6}" * (len(d) - 1) 
for row in zip(*table): 
    print(fmt.format(*row)) 

tsvfmt = "\t".join(["{}"]*len(d)) 
for row in zip(*table): 
    print(tsvfmt.format(*row)) 
関連する問題