繁体   English   中英

Python-来自CSV文件的字典,每个键具有多个值

[英]Python - Dictionary from CSV file with Multiple Values per Key

我正在尝试从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={'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()

感谢您抽出宝贵的时间阅读。 任何帮助将不胜感激。

这是使用常规词典的版本。 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))])

试试这个,我想这就是你想要的。 注意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'])

您可能实际上需要嵌套的字典结构; 保留一个列表,然后尝试将索引与食物名称匹配会很快出现毛病。

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))

使用字典的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”不存在,它使用提供的默认值创建它。 在这种情况下,默认值为空列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM