明显的循环问题:为什么我一遍又一遍地向列表添加相同的东西



我试图将。csv的每一行都变成字典(键是。csv的第一行),然后我试图将这些字典中的每个放入列表中。当我运行这段代码时,我最终一遍又一遍地将.csv的LAST ROW追加到列表中,而不是正确地将每个字典(临时保存为dataLine)追加到列表中。这就更令人困惑了,因为如果我把代码中的" datlist .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()

您可以尝试使用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]

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

这里我使用的CSV是这样的:

title1,title2
something,another
cool,stuff

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

移动dataline = {}到外循环:

for row in reader:
    dataLine = {}

在您的代码中,dataLine只是对特定对象的引用。每次迭代之后,这个对象都会改变。因此列表dataList存储了相同对象的序列。

用这个代替:

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

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

相关内容

最新更新