我正在尝试用python中的csv文件创建一个字典。假设CSV包含:
Student food amount
John apple 15
John banana 20
John orange 1
John grape 3
Ben apple 2
Ben orange 4
Ben strawberry 8
Andrew apple 10
Andrew watermelon 3
我想象的是一个字典,其键将是学生姓名,列表作为每个条目对应不同食物的值。 我必须计算第二列中唯一食物的数量,这将是向量的长度。 例如:
The value of [15,20,1,3,0,0] would correspond to [apple, banana, orange, grape, strawberry, watermelon] for 'John'.
The value of [2,0,4,0,8,0] would correspond to [apple, banana, orange, grape, strawberry, watermelon] for 'Ben'.
The value of [10,0,0,0,0,3] would correspond to [apple, banana, orange, grape, strawberry, watermelon] for 'Andrew'
dict的预期输出如下所示:
dict={'John':{[15,20,1,3,0,0]}, 'Ben': {[2,0,4,0,8,0]}, 'Andrew': {[10,0,0,0,0,3]}}
我在创建字典时遇到了麻烦,或者字典是否是正确的方法。我必须从头开始:
import csv
data_file=open('data.csv','rU')
reader=csv.DictReader(data_file)
data={}
for row in reader:
data[row['Student']]=row
data_file.close()
感谢您花时间阅读。任何帮助将不胜感激。
答案 0 :(得分:3)
这是使用常规字典的版本。 Defaultdict肯定更好。
import csv
data_file=open('data.csv','rU')
reader=csv.DictReader(data_file)
data={}
for row in reader:
if row['Student'] in data:
data[row['Student']].append(row['amount'])
else:
data[row['Student']] = [row['amount']]
data_file.close()
编辑:
For matching indicies
import csv
from collections import defaultdict
data_file=open('data.csv','rU')
reader=csv.DictReader(data_file)
data=defaultdict(lambda:[0,0,0,0])
fruit_to_index = defaultdict(lambda:None,{'apple':0,'banana':1,'orange':2,'grape':3})
for row in reader:
if fruit_to_index[row['food']] != None:
data[row['Student']][fruit_to_index[row['food']]] = int(row['amount'])
data_file.close()
print data
将是
defaultdict(<function <lambda> at address>,
{'John': [15, 20, 1, 3],
'Ben': [2 , 0 , 0, 0],
'Andrew': [10, 0 , 0, 0]})
我认为这就是你想要的。
EDIT2: 当水果列表不包括草莓和西瓜时,这样做,但应该很容易添加。 如果列表太大
生成水果到索引的映射
set_of_fruits = set()
for row in reader:
set_of_fruits.add(row['food'])
c = 0
for e in set_of_fruits:
fruit_to_index[e] = c
c += 1
请注意,不会生成set_of_fruits的顺序。
data = defaultdict(lambda:[0,0,0,0])
变为
data = defaultdict(lambda:[0 for x in range(len(set_of_fruits))])
答案 1 :(得分:1)
试试这个,我想这就是你想要的。注意defaultdict的用法,可以使用常规字典来完成,但在这种情况下,defaultdict非常方便:
import csv
from collections import defaultdict
data=defaultdict(list)
with open('data.csv','rb') as data_file:
reader=csv.DictReader(data_file)
for row in reader:
data[row['Student']].append(row['amount'])
答案 2 :(得分:0)
你可能真的想要一个嵌套的字典结构;保持一个列表,然后尝试将索引与食物名称匹配将变得毛茸茸。
import csv
from collections import defaultdict
data = defaultdict(dict)
with open('data.csv', 'r') as file:
reader = csv.DictReader(file)
for row in reader:
data[row['Student']][row['food']] = row['amount']
这会给你一个像这样的结构:
{'John': {'apple': 15, 'banana': 20, 'orange': 1},
'Ben': {'apple': 2, 'watermelon': 4}, #etc.
}
这可以让你查找特定的食物,而不必尝试交叉引用另一个列表来找出在哪里找到计数,并支持任意数量的食物项目,而无需用所有缺失的零填充你的列表。
如果你想要超赞,你可以使用嵌套的defaultdict
,这样查找未输入的食物会自动返回零,而不是给KeyError
;只需将第二行更改为:
data = defaultdict(lambda: defaultdict(int))
答案 3 :(得分:0)
使用dict的setdefault方法。
import csv
data_file=open('data.csv','rU')
reader=csv.DictReader(data_file)
data={}
for row in reader:
data.setdefault(row['Student'], []).append(row['amount'])
data_file.close()
如果是钥匙,例如。 “John”不存在,它使用提供的默认值创建它。在这种情况下,空列表是默认值。