尝试将表(此处为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]
任何帮助将不胜感激。
答案 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
方法传递的同一列表对象。