Skip to content
Advertisement

Python: convert dictionary into a cvs file

This is my current code:

import csv
data = {'name' : ['Dave', 'Dennis', 'Peter', 'Jess'],
        'language': ['Python', 'C', 'Java', 'Python']}

new_data = []
for row in data:
    new_row = {}
    for item in row:
        new_row[item['name']] = item['name']
    new_data.append(new_row)

print(new_data)
header = new_data[0].keys()
print(header)

with open('output.csv', 'w') as fh:
    csv_writer = csv.DictWriter(fh, header)
    csv_writer.writeheader()
    csv_writer.writerows(new_data)

What I am trying to achieve is that the dictionary keys are turned into the csv headers and the values turned into the rows.

But when running the code I get a TypeError: 'string indices must be integers' in line 21.

Advertisement

Answer

Problem

The issue here is for row in data. This is actually iterating over the keys of your data dictionary, and then you’re iterating over the characters of the dictionary keys:

In [2]: data = {'name' : ['Dave', 'Dennis', 'Peter', 'Jess'],
   ...:         'language': ['Python', 'C', 'Java', 'Python']}
   ...:
   ...: new_data = []
   ...: for row in data:
   ...:     for item in row:
   ...:         print(item)
   ...:
n
a
m
e
l
a
n
g
u
a
g
e

Approach

What you actually need to do is use zip to capture both the name and favorite language of each person at the same time:

In [43]: for row in zip(*data.values()):
    ...:     print(row)
    ...:
('Dave', 'Python')
('Dennis', 'C')
('Peter', 'Java')
('Jess', 'Python')

Now, you need to zip those tuples with the keys from data:

In [44]: header = data.keys()
    ...: for row in zip(*data.values()):
    ...:     print(list(zip(header, row)))
    ...:
[('name', 'Dave'), ('language', 'Python')]
[('name', 'Dennis'), ('language', 'C')]
[('name', 'Peter'), ('language', 'Java')]
[('name', 'Jess'), ('language', 'Python')]

Solution

Now you can pass these tuples to the dict constructor to create your rowdicts which csv_writer.writerows requires:

header = data.keys()
new_data = []
for row in zip(*data.values()):
    new_data.append(dict(zip(header, row)))

with open("output.csv", "w+", newline="") as f_out:
    csv_writer = csv.DictWriter(f_out, header)
    csv_writer.writeheader()
    csv_writer.writerows(new_data)

Output in output.csv:

name,language
Dave,Python
Dennis,C
Peter,Java
Jess,Python
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement