Reputation: 13
Please don't be brutal! I'm new to coding and have looked all over the web to find answers. I have a CSV with column one listing names, column 2 listing jobs, and column 3 listing birth months. I want the output I typed below the code. I have the dictionary made, but it is in this format: {"Karen Fisher": ("IT","November"), etc.} I want the keys of the nested dictionaries to be from the header of the csv so that people know what kind of data they are looking at about each person. I'm getting this error: "TypeError: 'tuple' object does not support item assignment"
with open("Example1.csv", "r") as csvfile:
csvreader = csv.reader(csvfile, delimiter=',')
row1 = next(csvreader)
#print(row1)
def makeadictionary(csvreader):
dct = {}
keys = []
valuesdict = {}
names = []
next(csvreader)
for row in csvreader:
keys.append(row[0])
dct[row[0]] = row[1],row[2]
names.append(row[0])
#print(names)
for key,value in dct.items():
value = list(value)
#print(value)
job = value[0]
#print(job)
birthmonth = value[1]
#print(birthmonth)
dct[key][row1[1]] = job
dct[key][row1[2]] = birthmonth
return dct
print(makeadictionary(csvreader))
Goal output: {"Karen Fisher":{"job": "IT", "birth month": "November"}, etc.}
Upvotes: 0
Views: 1087
Reputation: 106
Take a look at the following line in your code:
dct[row[0]] = row[1],row[2]
This creates a a dictionary of the following form:
{"Karen Fisher": ("IT", "November")}
Note that "Karen Fisher" maps to a tuple of size 2, that is, if you access dct["Karen Fisher"]
you get the tuple ("IT", "November")
. Now look at the line causing the error:
dct[key][row1[1]] = job
We know that dct[key]
is equal to ("IT", "November")
and that row1[1]
is equal to "job"
, so what python is trying to execute is the following expression:
("IT", "November")["job"] = job
So the structure of this is a[b] = c
where a
is a tuple. This doesn't work for a couple of reasons, one of them that you can't do an indexed assignment of that form for a tuple (tuples can only be created, but not modified), the other is that you can't index a tuple with a string.
What you seem to want to do is to assign an item in a dictionary, but you don't have a dictionary in hand: dct
is a dictionary, but dct[key]
is a tuple. What you can do is instead create a dictionary:
dct[key] = {row1[1]: job, row1[2]: birthmonth]}
This should work, but there's another little issue. It's generally not good practice to modify a dictionary while you're iterating through it. You also don't need to iterate through everything twice. And I think you have a bug where you skip your first line of data after the header (in the next(csvreader)
call in makeadictionary
). Finally, you don't need to create a nested function for what you want to accomplish.
What I would recommend is the following:
with open("Example1.csv", "r") as csvfile:
csvreader = csv.reader(csvfile, delimiter=',')
header_row = next(csvreader)
result = {}
for row in csvreader:
name = row[0]
result[name] = {}
for field_name, value in zip(header_row[1:], row[1:]):
# The zip function 'mixes' the two lists:
# zip([a, b, c], [d, e, f]) == [(a, d), (b, e), (c, f)]
result[name][field_name] = value
print(result)
Upvotes: 1
Reputation: 54718
The csv.DictReader class will return you a dictionary. All you have to do is store the entries by key:
from pprint import pprint
import csv
f = open('x.csv','r')
track = {}
for row in csv.DictReader(f):
track[row['name']] = dict(row)
pprint( track )
Output:
{'Joe Blow': {'birth month': 'April', 'job': 'HR', 'name': 'Joe Blow'},
'Karen Fisher': {'birth month': 'November',
'job': 'IT',
'name': 'Karen Fisher'}}
Upvotes: 1