2016-11-27 4 views
0

Попытка написать ниже словарь в файл csv с желаемым выходом, как указано ниже.Python - конвертировать словарь (имеющий «список» как значения) в файл 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 
+0

В вашем «желаемом выходе» есть третья строка, которая должна быть «,, def», чтобы поставить «def» в третьем столбце (т. Е. Один с надписью «2»)? –

+0

@ K.A.Buhr: Да. «def» следует поместить в третий столбец справа под «abc». – MSH

ответ

0

Вот полное решение:

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() 
0

следующие работы в 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, которую я выбрал u p от here. Он превращает список столбцов в список строк, автоматически заполняя столбцы, которые слишком коротки, с None. К счастью, csv writer выводит пробелы для значений None, что и является необходимым.

(В Python 3, map ведет себя по-другому (без заполнения), так что это потребует некоторых изменений.)

Изменить: замена transpose функция, которая работает как для Python 2 и 3 является:

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

Спасибо за понимание @K. А. Бухр. Это очень заманчивый подход, но я немного обеспокоен несовместимостью версии функции карты. Я бы предпочел написать свою собственную функцию, чтобы добавить «Нет». – MSH

Смежные вопросы