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

Python-来自CSV文件的字典,每个键有多个值,python,csv,dictionary,Python,Csv,Dictionary,我正在尝试从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

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

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

试试这个,我想这是你想要的。请注意的用法,它可以通过常规词典完成,但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'])

试试这个,我想这是你想要的。请注意的用法,它可以通过常规词典完成,但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'])

这是一个使用普通字典的版本。不过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()
编辑:

打印数据

defaultdict(<function <lambda> at address>, 
{'John':  [15, 20, 1, 3], 
'Ben':    [2 , 0 , 0, 0], 
'Andrew': [10, 0 , 0, 0]})
请注意,不会生成集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合的顺序

data=defaultdict(lambda:[0,0,0,0])


data=defaultdict(lambda:[0代表范围内的x(len(水果的集合)))
这是一个使用常规字典的版本。不过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()
编辑:

打印数据

defaultdict(<function <lambda> at address>, 
{'John':  [15, 20, 1, 3], 
'Ben':    [2 , 0 , 0, 0], 
'Andrew': [10, 0 , 0, 0]})
请注意,不会生成集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合的顺序

data=defaultdict(lambda:[0,0,0,0])


data=defaultdict(lambda:[0代表范围内的x(len(水果的集合)))

您可能实际上想要一个嵌套字典结构;保留一个列表,然后尝试将索引与食物名称相匹配,这很快就会让人毛骨悚然

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
s;只需将第二行更改为:

data = defaultdict(lambda: defaultdict(int))

您可能实际上想要一个嵌套的字典结构;保留一个列表,然后尝试将索引与食物名称相匹配,这很快就会让人毛骨悚然

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
s;只需将第二行更改为:

data = defaultdict(lambda: defaultdict(int))

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

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

谢谢。我想我应该提一下最终目标是什么。我试图对不同学生之间的数量向量进行余弦相似性分析,因此我需要确保每个学生的食物名称索引匹配,如果他们没有食物名称,那么数量将填充为0。我想我应该提一下最终目标是什么。我试图对不同学生之间的数量向量进行余弦相似性分析,因此我需要确保每个学生的食物名称索引匹配,如果他们没有食物名称,那么数量将填充为0。这只会添加到列表中,但与食物名称的索引不匹配。这是因为你没有非常准确地描述你的问题。请更正示例预期输出。谢谢。这只会添加到列表中,但与食物名称的索引不匹配。这是因为你没有非常准确地描述你的问题。请更正示例预期输出。谢谢。然而,这只会添加到列表中,而不会将索引与食品名称相匹配。例如,由于Ben没有吃桔子,因此数量将填充为0。我希望尽量避免硬编码每个水果的索引,因为不幸的是,我的csv文件中有大约200个唯一的水果。请阅读编辑2。您只需使用
行['food']
生成一个水果饼列表。然而,这只会添加到列表中,而不会将索引与食品名称相匹配。例如,由于Ben没有吃桔子,因此数量将填充为0。我希望尽量避免硬编码每个水果的索引,因为不幸的是,我的csv文件中有大约200个唯一的水果。请阅读编辑2。您可以使用
行['food']
生成水果列表