从CSV提取数据并追加到字典的问题

时间:2018-11-21 21:57:50

标签: python arrays csv dictionary append

尝试将表(此处为CSV,但可能是其他表)中的数据单元插入字典列表时,我得到一个奇怪的结果。

import csv

keylist = ["ID", "RN", "PD"]
myID = 0
t = []
t.append(dict.fromkeys(keylist, []))

with open("dataset.csv") as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    for row in csv_reader:
        for j in range (len(row)):
            #printing here works as expected
            print keylist[j], row[j]
            #when appending to the value list the result is not as expected
            t[myID][keylist[j]].append(row[j])

出乎意料的结果似乎是将整个行添加到了行上,而不仅仅是行[j]上的项目。

例如,如果CSV类似于:

0, "foo", "bar"
0, "foo2", "bar2"
0, "foo3", "bar3"

t [0] [“ ID”]的结果为:

[0, "foo", "bar", 0, "foo2", "bar2", 0, "foo3", "bar3"]

而不是预期的结果:

[0, 0, 0]

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

dict.fromkeys使用所有键的初始值初始化,因此它们都获得列表的相同实例。这并不意味着要使用可变对象进行初始化。

如果密钥尚不存在,请使用collections.defaultdict创建新列表:

import csv
from collections import defaultdict

keylist = ['ID', 'RN', 'PD']
myID = 0
t = [defaultdict(list)]

with open('dataset.csv',newline='') as csv_file:            # Use newline='' per csv docs.
    csv_reader = csv.reader(csv_file,skipinitialspace=True) # handles spaces after commas.
    for row in csv_reader:
        for col,value in enumerate(row):
            t[myID][keylist[col]].append(value)

print(t[myID])import csv
from collections import defaultdict
keylist = ['ID', 'RN', 'PD']
myID = 0
t = [defaultdict(list)]

with open('dataset.csv',newline='') as csv_file:
    csv_reader = csv.reader(csv_file,skipinitialspace=True)
    for row in csv_reader:
        for i,v in enumerate(row):
            t[myID][keylist[i]].append(v)

print(t[myID])

输出:

defaultdict(<class 'list'>, {'ID': ['0', '0', '0'], 'RN': ['foo', 'foo2', 'foo3'], 'PD': ['bar', 'bar2', 'bar3']})

请注意,这仍然不能为您的零提供整数。您将需要更多代码。像这样:

    for col,value in enumerate(row):
            t[myID][keylist[col]].append(int(value) if col==0 else value)

输出:

defaultdict(<class 'list'>, {'ID': [0, 0, 0], 'RN': ['foo', 'foo2', 'foo3'], 'PD': ['bar', 'bar2', 'bar3']})

答案 1 :(得分:0)

我相信问题出在字典的初始化上:

dict.fromkeys(keylist, [])

在所有字典键之间共享同一列表对象,并且所有项目都附加到同一列表中。 以下初始化取得了正确的结果:

t.append({k: [] for k in keylist})

编辑:一个简单的例子来说明正在发生的事情:

a = b = []
a.append(3)
b.append('foo')
a

给予:

[3, 'foo']

由于a和b是不同的变量,因此它们引用的是同一对象。同样,在您的示例中,字典中的不同键都引用通过fromkeys方法传递的同一列表对象。