2015-07-12 147 views
3

假设我在下面的'players.csv'文件中有一些NFL球员的数据。我的目标是读取文件,并创建一个字典,其中键为玩家的身高,值为玩家个人资料列表。 (这是一个元组)阅读CSV文件并创建字典?

HEIGHT,NAME,DRAFTED,AGE,POSITION,WEIGHT 

6,Aaron,2005,31,QB,225 

5,Jordy,2008,30,WR,217 

5,Randall,2011,24,WR,192 

球员简介元组例如,“名称”必须是一个字符串和“年龄”和“位置”必须是整数。起草的'年份'和'立场'必须被忽略。

player_profile = (name, age, position) 

预期词典:

# players height are keys, player profiles are values. 
dict = { 
    6: [('Aaron', 31, 225)] 
    5: [('Jordy', 30, 217), ('Randall', 24, 192)] 
    } 

下面是我到目前为止,我卡住了。

final_dict = {} 

#open csv file 
with open(filename) as f: 
    info = f.read() 

#split the newline characters 
info2 = info.split() 

#exclude the header 
info3 = info2[1:] 
+1

看一看在文档csv.reader,它使这变得极其简单。 – pvg

回答

2

使用csv moduledefaultdict处理重复键:

import csv 
from collections import defaultdict 

d = defaultdict(list) 

with open("in.csv") as f: 
    next(f) # skip header 
    r = csv.reader(f) 
    # unpack use height as key and append name age and position 
    for h, nm, _, a, p ,_ in r: 
     d[int(h)].append((nm, int(a), p)) 

print(d) 

输出:

defaultdict(<type 'list'>, {5: [('Jordy', 30, 'WR'), ('Randall', 24, 'WR')], 6: [('Aaron', 31, 'QB')]}) 

如果你真的想避免进口的,你可以str.split并使用字典。 setdefault,但我看不到没有理由不使用内置库如csv和集合:

d = {} 

with open("in.csv") as f: 
    next(f) 
    for line in f: 
     h, nm, _, a, p ,_ = line.split(",") 
     d.setdefault(int(h),[]).append((nm, int(a), p)) 

print(d) 

输出:

{5: [('Jordy', 30, 'WR'), ('Randall', 24, 'WR')], 6: [('Aaron', 31, 'QB')]} 

你输入的例子是不正确的,POSITION是一个字符串,你应该考虑WEIGHT您期望的输出匹配:

with open("in.csv") as f: 
    next(f) # skip header 
    r = csv.reader(f) 
    # unpack use height as key and append name age and weight 
    for h, nm, _, a, _ ,w in r: 
     d[int(h)].append((nm, int(a), int(w))) 

输出:

defaultdict(<type 'list'>, {5: [('Jordy', 30, 217), ('Randall', 24, 192)], 6: [('Aaron', 31, 225)]}) 

使用正常词典进行相同的更改以获取相同的输出。

+0

有没有办法'import csv?'我正在寻找最简单的解决方案,无需导入任何东西。 –

+1

@VincentLuc,你为什么不导入,它可以通过拆分和使用dict.setdefault来实现,效率较低 –

0

csv模块的问题在于它不会自动处理数据类型转换,而且您可能已经从Padraic的回答中注意到,键是字符串,年龄也是如此。这反过来意味着您将需要一个额外的通行证,可能带有一个map,您将在其中将字符串转换为正确的类型。此外,读取文件后,您可能希望对其内容执行某种分析或其他处理。

出于这个原因,我想提出一个pandas.DataFrame,提供类似于字典的行为如下工作:

import pandas 
Q = pandas.read_csv("myfile.csv", index_col = "HEIGHT") 

Q现在是一个DataFrame。要检索所有玩家为5的高度:

Q.ix[5] #Returns two rows according to the data posted in the question. 

要获得高度5的球员平均年龄:

Q.ix[5]["AGE"].median() #27.0 according to the data posted in the question. 

欲了解更多关于熊猫请参阅this link

希望这会有所帮助。

0

我觉得这是最基本的解决了这个问题

from collections import defaultdict 

players = defaultdict(list) 
for line in open("players.csv"): 
    line = line.strip() 
    tokens = line.split(",") 
    xs = [tokens[1], tokens[3], tokens[5]] 
    players[tokens[0]].append(tuple(xs)) 

首先要定义列表作为默认值的dict所有。然后你通过文件,我们必须去掉一些特殊字符,如“\ n”等。然后我们用“,”分割整行。然后我们知道在哪里。我们知道这个数字处于零位,所以这是我们的关键。其他属性分别位于第1,第3和第5位,因此我们还在我们的列表中包含这些标记。我们将这个标记包含在列表中,以便将此列表转换为元组。这是最简单的解决方案。我们也可以说,这样的事情

players[tokens[0]].append((tokens[1], tokens[3], tokens[5])) 

这也将工作:)

问候, golobich