2

我试图将 .csv 的每一行转换为字典(键是 .csv 的第一行),然后我试图将这些字典中的每一个放入一个列表中。当我运行此代码时,我最终将 .csv 的 LAST ROW 一遍又一遍地附加到列表中,而不是正确地将每个字典(临时保存为 dataLine)附加到列表中?这更加令人困惑,因为如果我将代码中的“dataList.append(dataLine)”行替换为“print 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()
4

3 回答 3

2

您多次插入对同一字典 ( dataLine)的引用。dataList您在此过程中更改了字典的内容,但它仍然是相同的对象。

进入dataline = {}你的外循环:

for row in reader:
    dataLine = {}
于 2013-01-21T17:37:07.997 回答
2

您可以尝试的一件事是使用内置的DictReadercsv

>>> 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实际上做了你所描述的 - 它使用第一行作为列标题,并从每个后续行创建一个字典,其中键是列标题,值是该行的列值。Usingwith是一种确保您的文件在不再需要时正确关闭的方法,这一行:

my_rows = [row for row in reader]

是一个列表推导式,它遍历reader并将每一行放入结果列表中(标题行除外)。

在这里,我使用了一个看起来像这样的 CSV:

title1,title2
something,another
cool,stuff
于 2013-01-21T17:38:40.953 回答
0

在您的代码dataLine中只是对特定对象的引用。每次迭代后,此对象都会更改。所以列表dataList存储的是同一个对象的序列。

改用这个:

dataLine = {key:row[i] for i, key in enumerate(keys)}

在这种情况下,您每次迭代都会创建新字典。

于 2013-01-21T17:40:28.003 回答