阅读CSV文件并创建字典?

时间:2015-07-12 21:06:34

标签: python list csv dictionary tuples

让我们说我有一个' players.csv'以下是一些NFL球员的数据。我的目标是读取文件,并创建一个字典,其中键作为玩家的高度,值作为玩家档案列表。 (这是一个元组)

HEIGHT,NAME,DRAFTED,AGE,POSITION,WEIGHT

6,Aaron,2005,31,QB,225

5,Jordy,2008,30,WR,217

5,Randall,2011,24,WR,192

玩家个人资料元组示例,'名称'必须是一个字符串和' age'和'位置'必须是整数。 '年'起草和'职位'必须被忽略。

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:]

3 个答案:

答案 0 :(得分: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并使用dict.setdefault,但我认为没有理由不使用像csv和collections这样的内置库:

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

使用普通字典进行相同的更改以获得相同的输出。

答案 1 :(得分: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

希望这有帮助。

答案 2 :(得分: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))

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

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

它也可以工作:)

此致 golobich