我正在尝试将.csv的每一行转换为字典(键是.csv的第一行),然后我试图将每个字典放入列表中。当我运行这段代码时,我最后一遍又一遍地将.csv的最后一行附加到列表中,而不是将每个字典(暂时保存为dataLine)正确附加到列表中?这更令人困惑,因为如果我用“print dataLine”替换我的代码中的“dataList.append(dataLine)”行,代码将遍历.csv并单独打印每一行而不是一遍又一遍地打印最后一行试。
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()
答案 0 :(得分:2)
您将同一字典(dataLine
)的引用多次插入dataList
。您沿途更改了字典的内容,但它仍然是同一个对象。
将dataline = {}
移到您的外圈:
for row in reader:
dataLine = {}
答案 1 :(得分:2)
您可以尝试的一件事是使用csv
中的内置DictReader类:
>>> 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
实际上是你所描述的 - 它使用第一行作为列标题,并从每个后续行创建一个字典,其中键是列标题,值是该列的列值行。使用with
是一种确保文件在不再需要时正确关闭的方法,这一行:
my_rows = [row for row in reader]
是list comprehension迭代reader
并将每一行放在结果列表中(标题行除外)。
我在这里使用了一个如下所示的CSV:
title1,title2
something,another
cool,stuff
答案 2 :(得分:0)
在您的代码中dataLine
只是对特定对象的引用。每次迭代后,此对象都会更改。因此列表dataList
存储同一对象的序列。
请改用:
dataLine = {key:row[i] for i, key in enumerate(keys)}
在这种情况下,您每次迭代都会创建新词典。