如何解决从txt文件中读取行并创建一个字典,其中的值是元组列表
student.txt:
Akçam Su Tilsim PSYC 3.9
Aksel Eda POLS 2.78
Alpaydin Dilay ECON 1.2
Atil Turgut Uluç IR 2.1
Deveci Yasemin PSYC 2.9
Erserçe Yasemin POLS 3.0
Gülle Halil POLS 2.7
Gündogdu Ata Alp ECON 4.0
Gungor Muhammed Yasin POLS 3.1
Hammoud Rawan IR 1.7
Has Atakan POLS 1.97
Ince Kemal Kahriman IR 2.0
Kaptan Deniz IR 3.5
Kestir Bengisu IR 3.8
Koca Aysu ECON 2.5
Kolayli Sena Göksu IR 2.8
Kumman Gizem PSYC 2.9
Madenoglu Zeynep PSYC 3.1
Naghiyeva Gulustan IR 3.8
Ok Arda Mert IR 3.2
Var Berna ECON 2.9
Yeltekin Sude PSYC 1.2
您好,我想编写一个函数,该函数将文件中有关每个学生的信息读入字典中,字典中的键是部门,值是给定部门中的学生列表(元组列表)。有关每个学生的信息存储在元组中 包含(姓氏,GPA)。文件中的学生可能有多个名字,但只会存储姓氏和gpa。该函数应返回字典。 (姓氏是每行的第一个单词。)
这是我尝试过的:
def read_student(ifile):
D={}
f1=open(ifile,'r')
for line in f1:
tab=line.find('\t')
space=line.rfind(' ')
rtab=line.rfind('\t')
student_surname=line[0:tab]
gpa=line[space+1:]
department=line[rtab+1:space]
if department not in D:
D[department]=[(student_surname,gpa)]
else:
D[department].append((student_surname,gpa))
f1.close()
return D
print(read_student('student.txt'))
我认为主要的问题是存在某种混乱,因为有时制表符出现在单词之后,而空格则出现在单词之后,所以我不知道在这种情况下如何正确使用find函数。
解决方法
请参阅下文-您将不得不处理姓氏,但问题中的其他详细信息已得到处理
from collections import defaultdict
data = defaultdict(list)
with open('data.txt',encoding="utf-8") as f:
lines = [l.strip() for l in f.readlines()]
for line in lines:
first_space_idx = line.rfind(' ')
sec_space_idx = line.rfind(' ',first_space_idx - 1)
grade = line[first_space_idx+1:]
dep = line[sec_space_idx:first_space_idx]
student = line[:sec_space_idx].strip()
data[dep].append((student,grade))
for dep,students in data.items():
print(f'{dep} --> {students}')
输出
PSYC --> [('Akçam Su Tilsim','3.9'),('Deveci Yasemin','2.9'),('Kumman Gizem',('Madenoglu Zeynep','3.1'),('Yeltekin Sude','1.2')]
POLS --> [('Aksel Eda','2.78'),('Erserçe Yasemin','3.0'),('Gülle Halil','2.7'),('Gungor Muhammed Yasin',('Has Atakan','1.97')]
ECON --> [('Alpaydin Dilay','1.2'),('Gündogdu Ata Alp','4.0'),('Koca Aysu','2.5'),('Var Berna','2.9')]
IR --> [('Atil Turgut Uluç','2.1'),('Hammoud Rawan','1.7'),('Ince Kemal Kahriman','2.0'),('Kaptan Deniz','3.5'),('Kestir Bengisu','3.8'),('Kolayli Sena Göksu','2.8'),('Naghiyeva Gulustan',('Ok Arda Mert','3.2')]
,
为什么只用rfind
就和find
和split
混在一起了?
def read_student(ifile):
D = {}
f1 = open(ifile,'r')
for line in f1:
cols = line.split() # Splits at one or more whitespace
surname = cols[0].strip()
department = cols[-2].strip() # Because you know the last-but-one is dept
gpa = float(cols[-1].strip()) # Because you know the last one is GPA
fname = ' '.join(cols[1:-2]).strip()
# cols[1:-2] gives you everything starting at col 1 up to but excluding the second-last.
# Then you join these with spaces.
if department not in D:
D[department] = [(surname,gpa)]
else:
D[department].append((surname,gpa))
f1.close()
return D
如果您知道自己的列始终用\t
分隔,则可以改为使用cols = line.split('\t')
。然后,在第二列中有学生的姓名,在第三列中有部门,在第四列中有GPA。
一些建议:
- 您可以使用
defaultdict
来避免每次检查if department not in D
- 您可以使用
with
来管理文件的读取,因此您不必担心f1.close()
。这是在Python中读取文件的首选方式。
您可以使用rsplit(' ',1)
提取姓氏。它给出了包含两个元素的列表。第一个是姓。然后再次拆分第二个元素以使用def read_student(ifile):
d = {}
with open(ifile) as fp:
for line in fp:
fname,data = line.strip().split(' ',1)
data,gpa = data.rsplit(' ',1)
dept = data.split()[-1]
d.setdefault(dept,[]).append((fname,gpa))
return d
print(read_student('student.txt'))
。它再次给出具有两个元素的列表,第一个是name和dept,第二个是gpa。再次拆分第二个元素以获得部门。
{'ECON': [('Alpaydin',('Gündogdu',('Koca',('Var','2.9')],'IR': [('Atil',('Hammoud',('Ince',('Kaptan',('Kestir',('Kolayli',('Naghiyeva',('Ok','3.2')],'POLS': [('Aksel',('Erserçe',('Gülle',('Gungor',('Has','1.97')],'PSYC': [('Akçam',('Deveci',('Kumman',('Madenoglu',('Yeltekin','1.2')]}
输出:
{{1}},
此解决方案利用itemgetter简化了变量的获取:姓氏,部门。和gpa
from operator import itemgetter
d = dict()
with open('f0.txt','r') as f:
for line in f:
name,dept,gpa = itemgetter(0,-2,-1)(line.split())
d.setdefault(dept,[]).append((name,gpa))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。