让我们说我有一个' 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:]
答案 0 :(得分:2)
使用csv module和defaultdict来处理重复键:
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