python - 如何将嵌套字典的内容写入特定格式的文件?

标签 python output output-formatting

我有一本字典,我正在尝试以某种方式输出其中的信息,以便它可用于下游分析。注意:dict 中的所有键也在 list 中。

for item in list:
    for key, value in dict[item].items():
        print item, key, value

这是我最接近我想要的,但还有很长的路要走。理想情况下,我想要的是:

     item1  item2  item3  item4
key1 value  value  value  value
key2 value  value  value  value
key2 value  value  value  value

这可能吗?

最佳答案

首先,如果我理解你的结构,列表只是为外部字典的键排序的一种方式,你的很多复杂性是试图将这两者一起使用来模拟一个有序的字典。如果是这样,有一种更简单的方法:使用 collections.OrderedDict .我会在最后回到这一点。


首先,您需要获取子词典的所有键,因为这些是您输出的行。

从评论来看,似乎 dct 中的所有子词典都具有相同的键,因此您可以从其中任意一个中提取键:

keys = dct.values()[0].keys()

如果每个子词典可以有不同的键子集,您需要先遍历 dct 来获取所有键:

keys = reduce(set.union, map(set, dct.values()))

有些人发现 reduce 很难理解,即使您实际上只是将它用作“sum with a different operator”。对于他们来说,这里是如何明确地做同样的事情:

keys = set()
for subdct in dct.values():
    keys |= set(subdct)

现在,对于每个键的行,我们需要为每个子字典(即外部字典中的每个值)获取一列,按照使用列表的元素作为键进入外部字典指定的顺序.

因此,对于每一列item,我们要得到item中key对应的外字典值,然后在得到的子字典中,得到对应于行的 key 的值。这在英语中很难说,但在 Python 中,它只是:

dct[item][key]

如果您实际上并没有在所有子词典中使用所有相同的键,那么它只会稍微复杂一些:

dct[item].get(key, '')

所以,如果你不想要任何标题,它看起来像这样:

with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter='\t')
    for key in keys:
        w.writerow(dct[item].get(key, '') for item in lst)

要添加标题列,只需将标题(在本例中为 key)添加到每一行:

with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter='\t')
    for key in keys:
        w.writerow([key], [dct[item].get(key, '') for item in lst])

请注意,我将 genexp 转换为列表理解,因此我可以使用列表连接来添加 key。将其保留为迭代器在概念上更清晰,并在前面加上 itertools.chain ,但在像这样带有微小迭代的微不足道的情况下,我认为这只会让代码更难阅读:

with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter='\t')
    for key in keys:
        w.writerow(chain([key], (dct[item].get(key, '') for item in lst)))

您还需要标题行。那更容易;它只是列表中的项目,标题列前面有一个空白列:

with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter='\t')
    w.writerow([''] + lst)
    for key in keys:
        w.writerow([key] + [dct[item].get(key, '') for item in lst])

但是,有两种方法可以使事情变得更简单。

首先,您可以使用 OrderedDict,因此您不需要单独的键列表。如果您坚持使用单独的 listdict,您仍然可以即时构建一个 OrderedDict 以使您的代码更易于阅读。例如:

od = collections.OrderedDict((item, dct[item]) for item in lst)

现在:

with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter='\t')
    w.writerow([''] + od.keys())
    for key in keys:
        w.writerow([key] + [subdct.get(key, '') for subdct in od.values()])

其次,您可以构建转置结构:

transposed = {key_b: {key_a: dct[key_a].get(key_b, '') for key_a in dct} 
              for key_b in keys}

然后以明显的顺序对其进行迭代(或使用 DictWriter 为您处理列的排序,并使用其 writerows 方法处理行,因此整个事情变成了一条线)。

关于python - 如何将嵌套字典的内容写入特定格式的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17224844/

相关文章:

python - 多字符串列映射和清理

python - 在范围内创建自定义数字数据类型?

python - 获取系列内的数组切片

使用命令行参数的 C 管道

r - 在 R 中抑制来自 zip 的消息

r - 查看数据帧的内容时是否可以截断输出?

Python 类成员类型提示

c - 文件中没有输出

nlp - 以conll格式输出结果(POS-tagging, stanford pos tagger)

postgresql - psql 的替代输出格式,每行显示一列和列名