简体   繁体   English

Python:将嵌套字典写入 CSV

[英]Python: Writing Nested Dictionary to CSV

I'm trying to write a nested dictionary to a .csv file.我正在尝试将嵌套字典写入 .csv 文件。 Here is is a simple example:这是一个简单的例子:

import csv
import itertools

fields = [ 'org', '2015', '2014', '2013' ]
dw     = { 'orgname1': { '2015' : 2, '2014' : 1, '2013' : 1 },
           'orgname2': { '2015' : 1, '2014' : 2, '2013' : 3 },
           'orgname3': { '2015' : 1, '2014' : 3, '2013' : 1 }
        }

with open("test_output.csv", "wb") as f:
    w = csv.writer( f )
    years = dw.values()[0].keys()
    for key in dw.keys():
        w.writerow([key, [dw[key][year] for year in years]])

This gets me a table with two columns: the first contains orgname ;这为我提供了一个包含两列的表:第一列包含orgname the second contains [2, 1, 1] (or the corresponding values from the sub-dictionary).第二个包含 [2, 1, 1] (或子字典中的相应值)。 I'd like a table with four columns: one for orgname and then three for the corresponding list elements.我想要一个包含四列的表格:一列用于orgname ,然后三列用于相应的列表元素。

This looks like a job forDictWriter :这看起来像是DictWriter的工作:

import csv
import itertools
import sys

fields = [ 'org', '2015', '2014', '2013' ]
dw     = { 'orgname1': { '2015' : 2, '2014' : 1, '2013' : 1 },
           'orgname2': { '2015' : 1, '2014' : 2, '2013' : 3 },
           'orgname3': { '2015' : 1, '2014' : 3, '2013' : 1 }
        }

w = csv.DictWriter( sys.stdout, fields )
for key,val in sorted(dw.items()):
    row = {'org': key}
    row.update(val)
    w.writerow(row)

Alternative implementation using DictWriter and with headers使用DictWriter和标头的替代实现

import csv
import itertools

fields = [ 'org', '2015', '2014', '2013' ]
dw     = { 'orgname1': { '2015' : 2, '2014' : 1, '2013' : 1 },
           'orgname2': { '2015' : 1, '2014' : 2, '2013' : 3 },
           'orgname3': { '2015' : 1, '2014' : 3, '2013' : 1 }
        }

with open("test_output.csv", "wb") as f:
    w = csv.DictWriter(f, fields)
    w.writeheader()
    for k in dw:
        w.writerow({field: dw[k].get(field) or k for field in fields})

Output:输出:

org,2015,2014,2013
orgname1,2,1,1
orgname3,1,3,1
orgname2,1,2,3

Change:改变:

w.writerow([key, [dw[key][year] for year in years]])

To:到:

w.writerow([key] + [dw[key][year] for year in years])

Otherwise, you try to write something like [orgname1, [2, 1, 1]] to the csv, while you mean [orgname1, 2, 1, 1] .否则,您尝试将[orgname1, [2, 1, 1]]写入 csv,而您的意思是[orgname1, 2, 1, 1]

As Padraic mentioned, you may want to change years = dw.values()[0].keys() to years = sorted(dw.values()[0].keys()) or years = fields[1:] to avoid random behaviour.正如 Padraic 提到的,您可能希望将years = dw.values()[0].keys()更改为years = sorted(dw.values()[0].keys())years = fields[1:]到避免随机行为。

Using DictWriter there is no need in sorting the fields in advance, since w.writerow() will assure the correct order.使用 DictWriter 不需要提前对字段进行排序,因为w.writerow()将确保正确的顺序。 But it does make sense to sort the items themselves.但对项目本身进行排序确实有意义。

So putting together all the above suggestions and picking the best of each, i would come up with following code:因此,将上述所有建议放在一起并从中挑选最好的,我会想出以下代码:

import csv
import itertools

def mergedict(a,b):
    a.update(b)
    return a

fields = [ 'org', '2015', '2014', '2013' ]
dw     = { 'orgname1': { '2015' : 2, '2014' : 1, '2013' : 1 },
           'orgname2': { '2015' : 1, '2014' : 2, '2013' : 3 },
           'orgname3': { '2015' : 1, '2014' : 3, '2013' : 1 }
        }

with open("test_output.csv", "wb") as f:
    w = csv.DictWriter( f, fields )
    w.writeheader()
    for k,d in sorted(dw.items()):
        w.writerow(mergedict({'org': k},d))

i added a tiny mergedict() function that makes it a one liner further down.我添加了一个微小的mergedict()函数,使它成为一个进一步向下的班轮。

I think this could be an easier way:我认为这可能是一种更简单的方法:

import csv

fields = [ 'org', '2015', '2014', '2013' ]
dw     = { 'orgname1': { '2015' : 2, '2014' : 1, '2013' : 1 },
           'orgname2': { '2015' : 1, '2014' : 2, '2013' : 3 },
           'orgname3': { '2015' : 1, '2014' : 3, '2013' : 1 }
        }

with open("test_output.csv", "w") as csv_file:
  csvwriter = csv.writer(csv_file)
  csvwriter.writerow(['org', '2015', '2014', '2013'])

  for org in dw:
     csvwriter.writerow(org, dw[org]['2015'], dw[org]['2014'], dw[org]['2013'])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM