Python:将嵌套字典写入 CSV
Posted
技术标签:
【中文标题】Python:将嵌套字典写入 CSV【英文标题】:Python: Writing Nested Dictionary to CSV 【发布时间】:2015-06-06 16:20:26 【问题描述】:我正在尝试将嵌套字典写入 .csv 文件。这是一个简单的例子:
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]])
这给我一个包含两列的表:第一列包含orgname
;第二个包含 [2, 1, 1] (或子字典中的相应值)。我想要一个有四列的表格:一列用于orgname
,然后三列用于对应的列表元素。
【问题讨论】:
dicts 没有顺序,所以你马上就有麻烦了 @PadraicCunningham 同意了。然而,他的钥匙似乎是按照字典顺序排列的。因此,他仍然可以通过对 dw.keys() 进行排序然后对其进行迭代来使其工作。 【参考方案1】:我认为这可能是一种更简单的方法:
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'])
【讨论】:
在最后一行中缺少括号以使其工作【参考方案2】:使用 DictWriter 无需预先对字段进行排序,因为w.writerow()
将确保正确的顺序。但是对项目本身进行排序确实很有意义。
所以综合以上所有建议并从中挑选出最好的,我会想出以下代码:
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))
我添加了一个很小的 mergedict()
函数,使其成为更下方的单线。
【讨论】:
【参考方案3】:使用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)
输出:
org,2015,2014,2013
orgname1,2,1,1
orgname3,1,3,1
orgname2,1,2,3
【讨论】:
我最喜欢您的回答,直截了当:) 您可以考虑按其键对dw
进行排序,因为在您的输出中,组织名称的顺序已从输入中改变。使用sorted(dw.items())
解决了这个问题
亲爱的 Python 3 用户,他们不想像我刚才所做的那样让自己感到尴尬,因为您只需将 open("test_output.csv", "wb")
切换为 open("test_output.csv", "w", newline='')
,上述解决方案就可以了完美无缺。否则你会得到一个a bytes-like object is required, not 'str' when writing to a file'
。不要像我一样尝试将整个字典编码为ascii
。
如果我的任何键的值为 0,那么如果 2015:0 用于 orgname1,我将键作为值,如 orgname1,orgname1,1,1。所以任何解决方案。 @Łukasz Rogalski【参考方案4】:
这看起来像是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)
【讨论】:
实际上你应该得到最好的评论,因为你是第一个完整的解决方案,我喜欢你使用 dicts 更新功能的方式。我在一个单独的函数中对其进行了调整,以便之后将其保持为一个衬里。所以我的答案几乎是你的,改为文件输出并添加标题:)【参考方案5】:变化:
w.writerow([key, [dw[key][year] for year in years]])
收件人:
w.writerow([key] + [dw[key][year] for year in years])
否则,您尝试将 [orgname1, [2, 1, 1]]
之类的内容写入 csv,而您的意思是 [orgname1, 2, 1, 1]
。
正如 Padraic 所说,您可能需要将 years = dw.values()[0].keys()
更改为 years = sorted(dw.values()[0].keys())
或 years = fields[1:]
以避免随机行为。
【讨论】:
如果您按照其他答案中的建议使用 DictWriter,则无需对年份进行排序 @hexereisoftware 是的,但现在只是复制。以上是关于Python:将嵌套字典写入 CSV的主要内容,如果未能解决你的问题,请参考以下文章