Python字典转换为CSV文件

46

我编写了一段代码,将CSV文件读入Python字典中,运行良好。现在我要将这个字典转换回CSV文件。我已经编写了以下代码:

import csv

itemDict={}

listReader = csv.reader(open('/Users/broberts/Desktop/Sum_CSP1.csv','rU'), delimiter = ',', quotechar='|')

for row in listReader:
    fID = row[0]
    fClassRange = row[1]
    fArea = row[2]

    if itemDict.has_key(fID):
        itemDict[fID][fClassRange]=fArea
    else:
        itemDict[fID] = {'5.0 to 5.25':'','5.25 to 5.5':'','5.5 to 5.75':'','5.75 to 6.0':'','6.0 to 6.25':'','6.25 to 6.5':'','6.5 to 6.75':'','6.75 to 7.0':'','7.0 to 7.25':'','7.25 to 7.5':'','7.5 to 7.75':'','7.75 to 8.0':'','8.0 to 8.25':'',}
        itemDict[fID][fClassRange]=fArea

listWriter = csv.writer(open('/Users/broberts/Desktop/Sum_CSP1_output.csv', 'wb'), delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)

for a in itemDict:
    print a
    listWriter.writerow(a)
在最后一个块中,listWriter不会向CSV文件写入任何内容,尽管它会打印a。我认为这与字典无序有关。我真的需要将fID以及与每个fID关联的每个键(例如"fClassRange",如"5.0到5.25")和与每个fClassRange相关联的值fArea写入CSV文件,但是我甚至还没有在代码中完成这一部分,因为我无法弄清楚如何写出fID。我研究了使用DictWriter,但我无法弄清楚如何告诉它所需的字段名称。

1
强烈推荐 Kenneth Reitz 的 tablib。它不仅可以满足你在这里所寻找的需求,而且还有很多其他功能。我想向其他人推荐这个库。它拥有一个出色、易于使用的 API,并且可以轻松地序列化为 csv、tsv、json、yaml 和 xlsx 等格式。 - floer32
8个回答

36

样本数据:

mydict = [{"col1": 1000, "col2": 2000}, {"col1": 3000, "col2": 4000}]

使用pandas将字典列表转换为CSV的一行代码:

import pandas as pd

pd.DataFrame(mydict).to_csv('out.csv', index=False)

结果:

col1,col2
1000,2000
3000,4000

1
非常好的回答!是否可以将这些值放在列而不是行中? - Carlos Junior

26

默认的 writer 需要一个列表,这就是为什么它对你不起作用的原因。要使用 dictwriter,只需将 listwriter= 一行更改为:

with open('/Users/broberts/Desktop/Sum_CSP1_output.csv', 'wb') as outfile:
    listWriter = csv.DictWriter(
       outfile,
       fieldnames=itemDict[itemDict.keys()[0]].keys(),
       delimiter=',',
       quotechar='|',
       quoting=csv.QUOTE_MINIMAL
    )

或者,如果你知道字段应该是什么,你可以将fieldnames设置为fieldnames=['arbitrary', 'list', 'of', 'keys']


哇,谢谢!但是现在我收到了这个消息:ValueError: 字典包含不在字段名称中的字段:4、6、3、3、9。 - bojo
抱歉,Spencer,我仍然收到相同的ValueError错误信息。 - bojo
非常感谢您的帮助。我尝试将“print a”更改为“print a.keys()”,只是为了看看会发生什么,结果得到:AttributeError: 'str' object has no attribute 'keys' -- 或许这表明存在问题?我还尝试使用DictWriter语句,其中“fieldnames = myFieldnames”,而“myFieldnames”等于您建议的默认类别范围列表,但我仍然遇到相同的ValueError。 - bojo
如果有帮助的话,让我描述一下问题和我想要做的事情。输入的 CSV 文件有多行。第一列包含一个 ID 号码,第二列包含一个类别范围,第三列包含一个面积值。第二行可能包含相同的 ID 号码,不同的类别范围和面积值,以此类推。ID 可以重复出现零次到半打次,具体取决于该 ID 号码适用的类别范围数量,每个类别范围都有一个面积。所有 ID 号码的类别范围都相同,但并非所有 ID 号码都拥有所有类别范围。 - bojo
@bojo 啊,打印 a.keys() 的部分很有见地。这意味着 itemDict 中没有字典。仔细想想,这是我的错误。我忽略了你使用了 for a in itemDict 这个语句。这是行不通的。你需要使用 for key,value in itemDict.iteritems() 语句。然后使用 listwriter.writerow(value) - Spencer Rathbun
显示剩余3条评论

5

使用writerows的示例:

import csv

def main():

    results = [
            {'File': 'test.txt', 'Temperature': 32.33, 'Day': 'Monday'},
            {'File': 'test2.txt', 'Temperature': 44.33, 'Day': 'Tuesday'},
            {'File': 'test3.txt', 'Temperature': 44.23, 'Day': 'Sunday'}
        ]

    with open('results.csv', 'w') as f:  
        w = csv.DictWriter(f, results[0].keys())
        w.writeheader()        
        w.writerows(results)                    
        
if __name__ == "__main__":
    main()  

这将导致生成名为 results.csv 的文件,其中包含:
File,Temperature,Day
test.txt,32.33,Monday
test2.txt,44.33,Tuesday
test3.txt,44.23,Sunday

3

这是我使用的,它简单易用并且对我来说效果很好。当你只有一个字典时,请使用此方法。

my_dict = {"tester": 1, "testers": 2}
with open('mycsvfile.csv', 'wb') as f:  
    w = csv.DictWriter(f, my_dict.keys())
    w.writerow(dict((fn,fn) for fn in my_dict.keys()))
    w.writerow(my_dict)

$ cat mycsvfile.csv
testers,tester
2,1

当你有一个字典列表,比如从SQL查询中获取的内容,你需要像这样操作。
my_dict = ({"tester": 1, "testers": 2},{"tester": 14, "testers": 28})
with open('mycsvfile.csv', 'wb') as f:  
    w = csv.DictWriter(f, my_dict[0].keys())
    w.writerow(dict((fn,fn) for fn in my_dict[0].keys()))
    w.writerows(my_dict)

cat mycsvfile.csv
testers,tester
2,1
28,14

2
w.writerow(dict((fn,fn) for fn in my_dict.keys())) 很酷,但是为什么不直接调用 w.writeheader() 呢?它做的事情一样,并且更易于理解。转置字典有什么好处吗? - Todor Minakov

1

为了后人:

在迭代字典时,应使用iteritems()方法,因此最后一部分变成:

for name, values in itemDict.iteritems():
    print values
    listWriter.writerow(values)

0

对我有帮助的是在打开文件时添加 newline="" 参数。

例如:

with open("sample.csv", "w", newline="") as outfile:
    writer = csv.writer(outfile)
    for num in range(0, 10):
        writer.writerow([num])

src


0
d = [{'a': 1, 'b': 2},{'a': 3, 'b': 4}]

with open('csv_file.csv', 'w', newline='\n') as f:
    w = csv.DictWriter(f, d[0].keys())
    w.writeheader()
    for i in d:
        w.writerow(i)

使您得到

a,b
1,2
3,4

1
你的答案格式似乎有问题——最后几行多了一个缩进 :) - Christian Scott

-1

最简单的方法

您可以将字典转换为数据框并将其写入csv文件 例如

import pandas as pd
my_dict = {"tester": 1, "testers": 2}
df=pd.DataFrame(my_dict,index=[0])
df.to_csv("path and name of your csv.csv")

输出

   tester  testers
0       1        2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接