Reputation: 909
I'm trying to turn every row of a .csv into a dictionary (keys are the first row of the .csv), and then I'm trying to put each of these dictionaries into a list. When I run this code, I end up appending the LAST ROW of the .csv to the list over and over again instead of appending each dictionary (saved temporarily as dataLine) to the list correctly? This is all the more confusing because if I replace the line "dataList.append(dataLine)" in my code with "print dataLine", the code iterates over the .csv and prints each row individually instead of printing the last row over and over again.
from sys import argv
import csv
# arguments
script, csvFile = argv
# check input
while csvFile.endswith(".csv") == False:
csvFile = raw_input("Please enter a *.csv file: ")
# open the csv file
openFile = open(csvFile, 'r')
# read the csv file
reader = csv.reader(openFile, delimiter=',')
# extract first row to use as keys
for row in range(1):
keys = reader.next()
# turn rows into dictionaries with keys
#FIX THIS PART!! NOT WORKING RIGHT!!!
length = len(keys)
dataLine = {}
dataList = []
for row in reader:
for i in range(length):
dataLine[keys[i]] = row[i]
dataList.append(dataLine)
for x in dataList:
print x
print ""
# close the file
openFile.close()
Upvotes: 2
Views: 157
Reputation: 37279
One thing you could try is using the built-in DictReader class in csv
:
>>> import csv
>>> with open('fake_csv.csv', 'r') as f:
... reader = csv.DictReader(f)
... my_rows = [row for row in reader]
...
>>> my_rows
[{'title1': 'something', 'title2': 'another'}, {'title1': 'cool', 'title2': 'stuff'}]
DictReader
actually does what you are describing - it uses the first row as the column titles and creates a dictionary from each subsequent row where the key is the column title and the value is the value of the column at that row. Using with
is a way to ensure that your files are properly closed when they are no longer needed, and this line:
my_rows = [row for row in reader]
Is a list comprehension that iterates through the reader
and puts each row in the resulting list (except for the header row).
Here I used a CSV that looked like this:
title1,title2
something,another
cool,stuff
Upvotes: 2
Reputation: 27611
In your code dataLine
is just a reference to a particular object. After each iteration this object changes. So the list dataList
stores the sequence of the same object.
Use this instead:
dataLine = {key:row[i] for i, key in enumerate(keys)}
In this case you create new dictionary every iteration.
Upvotes: 0
Reputation: 21517
You insert a reference to the same dictionary (dataLine
) into your dataList
multiple times. You change the content of dictionary along the way, but it remains the same object.
Move dataline = {}
into your outer loop:
for row in reader:
dataLine = {}
Upvotes: 2