【问题标题】:python write dictionary from csv filepython从csv文件写字典
【发布时间】:2017-01-26 03:09:26
【问题描述】:

我现在正在努力从 csv 文件中编写字典。

csv文件格式如下:

student,    Test 1, Test 2, Test 3, Final Exam
A,          9,      19,    9,       22
B,          10,     16,    9,       26
C,          11,     17,    8,       27
D,          7,      14,    9,       18
E,          8,      20,    8,       23
weight,     0.15,   0.25,  0.2,     0.4
max_points  12      20     9        30

其中 2-6 行是学生的姓名,即他们在每次考试中的考试成绩。 最后两行分别代表每次测试的权重和每次测试的满分。

现在,我想从此列表中创建一个字典,如下所示:

{'Test 1': {'weight': '0.15', 'max_points': '12'}, 
'Test 2': {'weight': '0.25', 'max_points': '20'}, 
'Test 3': {'weight': '0.2',   'max_points': '9'}, 
'Final Exam': {'weight': '0.4', 'max_points': '30'}}

其中键是csv文件中第一行的变量,除了变量students;在每个嵌套字典中,键是 csv 文件中第一列和最后两行的名称:weight、max_points。相应的值分别只是它们行中的值。

我现在唯一想到的是:

reader = csv.DictReader(open('gradebook.csv'))
for row in reader:
    key = row.pop('Student')

而且我不知道如何进行。非常感谢您的帮助!!!

【问题讨论】:

  • 如图所示,您的文件不是 CSV 文件。 CSV 文件中的列以逗号分隔。
  • @DYZ 在技术上是正确的,但现在将所有分隔的文本文件称为 CSV 已成为惯例。不说是对是错,只是说普通话。
  • @e4c5 将数字称为“数字”已成为普遍做法。这不会使他们成为数字,是吗?回归基础永远不会有坏处。
  • @DYZ 很抱歉造成混乱。我只是省略了逗号,但你明白我的意思吗?
  • @dyz 注意在pandas中,像上面这样读取文件的函数名为read_csv

标签: python csv dictionary


【解决方案1】:

使用 Pandas,它是单行的

import pandas as pd

df = pandas.read_csv('myfile.csv', delim_whitespace=True)
{ k: { 'max_points': df[k].max(), 'weight': df[k][5] } for k in df.keys()[1:] }

编辑。 哎呀,我看到 OP 实际上并不是在寻找 max()

{ k: { 'max_points': df[k][6], 'weight': df[k][5] } for k in df.keys()[1:] }

顺便说一句,如果 Pandas 无法正确识别您的标题

df = pd.read_csv('/tmp/df.txt',delim_whitespace=True, header=1, names=['Student','Test 1','Test 2','Test 3','Final Score'])

【讨论】:

  • 谢谢。但是我可以在不使用熊猫的情况下做到这一点吗?
  • 当然可以,最困难的是:-)
  • 这是一个很酷的解决方案,我需要更多地熟悉 pandas。我尝试了min() 的重量,但是来自 csv 的值不像二进制数那么好 :)
  • @JoshSmeaton 我也在学习中!你的回答也很好。 +1
  • 不客气。我很高兴能帮上忙。由于您还是新手,我可以指出,在这里说“谢谢”的首选方式是投票赞成好的问题和有用的答案(一旦您有足够的声誉这样做),并接受最有用的答案回答您提出的任何问题(这也可以稍微提升您的声誉)。 When someone answers
【解决方案2】:

这是一个不使用 pandas 的解决方案,应该做你想做的事。请注意,虽然我的 csv 文件是 实际 csv 文件,因此您可能需要相应地调整阅读器的创建。

In [13]: reader = csv.DictReader(open('tests.csv'))

In [14]: record = defaultdict(dict)

In [15]: for row in reader:
    ...:    if row['Student'] == 'weight':
    ...:        for header in reader.fieldnames[1:]:
    ...:            record[header]['weight'] = row[header]
    ...:    if row['Student'] == 'max_points':
    ...:        for header in reader.fieldnames[1:]:
    ...:            record[header]['max_points'] = row[header]


In [17]: from pprint import pprint

In [18]: pprint(record)
defaultdict(<class 'dict'>,
            {'Final Exam': {'max_points': '30', 'weight': '0.4'},
             'Test 1': {'max_points': '12', 'weight': '0.15'},
             'Test 2': {'max_points': '20', 'weight': '0.25'},
             'Test 3': {'max_points': '9', 'weight': '0.2'}})

如果您之前没有见过defaultdict,那么当您尝试访问一个尚不存在的键时,您传递给构造函数的任何值都会用作值。

【讨论】:

  • 谢谢。但是我可以在不访问这些密钥的情况下做到这一点吗?就像我可以不做记录['test 1']['weight'] = row['test 1'] 吗?
  • 如果你不想使用 pandas,你将不得不接受这个答案
  • @JoshSmeaton 谢谢。但这对我不起作用。如果我不使用 pprint,我得到了这个结果: defaultdict(, {})
  • @JoshSmeaton 当我使用 pprint 时,我仍然得到一个空字典。你知道怎么解决吗?
  • 我现在知道空字典的来源。我在前几行中使用了 row.pop('Student') 。都修好了!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-09-15
  • 2018-03-19
  • 1970-01-01
  • 2016-03-21
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多