Python - 将字典(具有 "list" 作为值)转换为 csv 文件

Python - Convert dictionary (having "list" as values) into csv file

正在尝试将以下字典写入 csv 文件,并具有如下所述的所需输出。

dict_data = {"1":["xyz"],
             "2":["abc","def"],
             "3":["zzz"]
            }

期望的输出:

1,3,2
xyz,zzz,abc
        def

下面的代码没有按预期工作,因为它将 "abc" 和 "def" 保存在同一个单元格中,如下所示。

with open('k.csv','wb') as out_file:
writer = csv.writer(out_file,dialect = 'excel')
headers =  [k for k in dict_data]
items = [dict_data[k] for k in dict_data]
writer.writerow(headers)
writer.writerow(items)

输出:

1,3,2
xyz,zzz,abc,def

完整的解决方案如下:

    import csv
    import os

    class CsvfileWriter:

        '''
        Takes dictionary as input and writes items into a CSV file.

        For ex:-

        Input dictionary:

        dict_data = {"1":["xyz"],"2":["abc","def"],"3":["zzz"]}

        Output: (CSV file)

        1,3,2
        xyz,zzz,abc
        ,,def

        '''

        def __init__(self,dictInput,maxLength=0):

            '''
            Creates a instance with following variables.
            dictInput & maxLength

            dictInput -> dictionary having values(list) of same length

            ex:-
                dict_data = {"1":["xyz",""],"2":["abc","def"],"3":["zzz",""]}

            maxLength -> length of the list

            '''
            self.dictInput = dictInput
            self.maxLength = maxLength

        @classmethod
        def list_padding(cls,dictInput):

            '''
            converts input dictionary having list (as values) of varying lenghts into constant length.
            Also returns class variables dictInput & maxLength

            Note:
            dictInput represents the dictionary after padding is applied.
            maxLength represents the length of the list(values in dictionary) having maximum number of items.

            Ex:-

            input dictionary:

            dict_data = {"1":["xyz"],"2":["abc","def"],"3":["zzz"]}

            output dictionary:

            dict_data = {"1":["xyz",""],"2":["abc","def"],"3":["zzz",""]}


            '''
            cls.dictInput = dictInput
            listValues =  dictInput.values()
            listValues.sort(key = lambda i: len(i))
            maxLength =  len(listValues[-1])

            for i in listValues:
                while(len(i) < maxLength):
                    i.append('')

            return cls(dictInput,maxLength)

        def write_to_csv(self):

            with open('sample_file.csv','wb') as out_file:
                writer = csv.writer(out_file,dialect = 'excel')
                headers =  [k for k in self.dictInput]
                items = [self.dictInput[k] for k in self.dictInput]
                writer.writerow(headers)
                c = 0
                while (c < self.maxLength):
                    writer.writerow([i[c] for i in items])
                    c += 1

    dict_data = {"1":["xyz"],"2":["abc","def"],"3":["zzz"]}

    cf = CsvfileWriter.list_padding(dict_data)

    cf.write_to_csv()

以下作品在 Python 2:

import csv

dict_data = {
    "1":["xyz"],
    "2":["abc","def"],
    "3":["zzz"]
}

def transpose(cols):
    return map(lambda *row: list(row), *cols)

with open('k.csv','w') as out_file:
    writer = csv.writer(out_file,dialect = 'excel')
    headers = dict_data.keys()
    items = transpose(dict_data.values())
    writer.writerow(headers)
    writer.writerows(items)

我不能把 transpose 函数归功于我,它是我从 here 学来的。它将列列表变成行列表,自动用 None 填充太短的列。幸运的是,csv 编写器为 None 值输出空白,这正是所需要的。

(在 Python 3 中,map 表现不同(无填充),因此需要进行一些更改。)

编辑:适用于 Python 2 和 3 的替换 transpose 函数是:

def transpose(cols):
    def mypop(l):
        try:
            return l.pop(0)
        except IndexError:
            return ''
    while any(cols):
        yield [mypop(l) for l in cols]