将嵌套的dict打印到tsv格式文件

时间:2016-04-25 17:02:37

标签: python

我有以下词典:

{'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

可以观察到,如果任何子集错过了'计数器',则零应该取而代之。 我尝试过不同的方法,但我无法实现。我可以使用简单的dict进行打印,但不能使用嵌套的打印:

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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))