python-3.x 将具有不同键的字典写入CSV文件

vsdwdz23  于 2023-03-04  发布在  Python
关注(0)|答案(4)|浏览(188)

我有一些字典:

d1 = {'name':'jon','age':4}
d2 = {'name':'joe','age':34,'height':100}

我还有其他字典没有在这里列出,它们有一些不同的键,但它们有一些与d1d2相同的键。

import csv
with open('file.csv', 'a') as f:
    wr = csv.writer(f) 
    wr.writerow(d1.values())
    wr.writerow(d2.values())

当然,这并没有把数据放在正确的列中,也没有生成所需的标题。我如何设置它,使每个字典中的每个键都成为一个标题,并且在将信息写入CSV时,值被放在正确的位置?

gdrx4gfi

gdrx4gfi1#

尝试使用csv.DictWriter(f, fieldnames=csv_columns)而不是csv.writer(f)查看文档here .至于csv_columns,如果你事先不知道所有的列名,你可以遍历所有的字典,找到唯一的列名并将它们添加到列表中.
我在下面写了一个例子。

import csv

d1 = {'name':'jon', 'age':4}
d2 = {'name':'joe', 'age':34, 'height':100}

csv_columns = ['name', 'age', 'height']

with open('file.csv', 'a') as f:
    wr = csv.DictWriter(f, fieldnames=csv_columns)
    wr.writeheader()
    wr.writerow(d1)
    wr.writerow(d2)
icomxhvb

icomxhvb2#

我认为处理这个问题的最好方法是创建一个类,跟踪您添加到其中的所有指令,然后为您编写文件。
这个类将允许你添加你想要的任意多的字典,并且将跟踪所有的字段,并将它们适当地添加到文件中。

class CsvDictWriter:
    def __init__(self):
        self.dicts = []
        self.fields = set()

    def add_dict(self, obj: dict):
        self.dicts.append(obj)
        self.fields.update(obj.keys())

    def write(self, file_name: str):
        with open(file_name, 'w') as fp:
            dw = DictWriter(fp, self.fields, restval='')
            dw.writeheader()
            for obj in self.dicts:
                dw.writerow(obj)

d1 = {'name': 'jon', 'age': 4}
d2 = {'name': 'joe', 'age': 34, 'height': 100}

cdw = CsvDictWriter()
cdw.add_dict(d1)
cdw.add_dict(d2)
cdw.write('file.csv')
iaqfqrcu

iaqfqrcu3#

你需要一个所有可能的键的列表,以及你希望它们写入csv的顺序。你不能“动态”地构建文件,因为你不知道每个字典包含哪些键,以及它们的顺序;除非您在开始将字典写入文件之前检查所有字典。
使用头(键)列表和DictWriter,您可以逐个完成并输出到文件。
DiscWriter类参数有一个restval,你需要它,因为不是所有的字典都有所有的键。它被描述为:
可选的restval参数指定字典在字段名中缺少键时要写入的值。

68bkxrlz

68bkxrlz4#

我发现这不是很好,但是它应该可以工作,而不需要知道所有列的名称。这将生成一个制表符分隔的csv字符串。结果可以很容易地写入文件

def exportArrayDicToCSV(arrayDict):
csvData = {}
headerString = ''
bodyString = ''
print(f"Processing Dictionary List")
for rowDataIndex in range(0, len(arrayDict)):
    print(f"{rowDataIndex + 1} out of {len(arrayDict)} rows processed")
    rowData = arrayDict[rowDataIndex]
    for header in rowData:
        if header not in csvData:
            csvData[header] = [""] * len(arrayDict)
        csvData[header][rowDataIndex] = rowData[header]
        
headerList = list(csvData.keys())
headerString = "\t".join(headerList)

print(f"generating CSV string")
for rowDataIndex in range(0, len(arrayDict)):
    print(f"{rowDataIndex + 1} out of {len(arrayDict)} rows processed")
    rowDataString = ''
    for fieldIndex in range(0, len(headerList)):
        rowDataString = f"{rowDataString}{csvData[headerList[fieldIndex]][rowDataIndex]}"
        if fieldIndex < len(headerList) - 1:
            rowDataString = f"{rowDataString}\t"
        
    bodyString = f"{bodyString}{rowDataString}"
    if rowDataIndex < len(arrayDict)-1:
        bodyString = f"{bodyString}\n"
return f"{headerString}\n{bodyString}"

相关问题