字典类型的嵌套
字典类型中,键值对的值可以是任意的数据类型,比如列表,元组,当然也可以是另一个字典
dt = {
'张三':{'学号':201111, '年级':2020, '专业':'计算机'},
'李四':{'学号':201112, '年级':2020, '专业':'英语'}
}
print(dt['张三']) #{'学号': 201111, '年级': 2020, '专业': '计算机'}
print(dt['李四']['年级']) #2020
下面po一道这学期让我印象很深的一道题:
现有一个文件oxforddata.txt ,包含一个城市多年的天气数据,部分内容为:
?其中第1,2 行是位置信息,3-5 行是表中一些特殊符号的说明,第6 行是下面表格的表头,第7 是表头的单位,从第8 行开始的就是具体的数据。
将上述文件的数据部分(即文件第8行开始)解析成一个多级字典,并返回这个字典。字典最外层键为年份(第一列),第二层键为月份(第二列),最内层键为其余列的数据项名(tmax, tmin, ...)
假设解析出来的字典名为dat ,那么当访问:
数据中缺失的部分(标注为--- )用Python 的None 值代替,数据上标注的一些特殊符号一律忽略。
第一步:打开文件,将"---"替换为"None",清除文件中的特殊符号
path = "src/step6/oxforddata.txt"
file_data=""
with open(path,"r",encoding="utf-8") as f:
for line in f:
if "---" in line:
line=line.replace("---","None")
if "*" in line:
line=line.replace("*","")
file_data+=line
with open(path,"w",encoding="utf-8") as f:
f.write(file_data)
顺便复习一下文件的打开模式:
?
第二步: 用split()将较难处理的字符串分割成列表。由于该文件从第八行才开始有具体数据,我们跳过前七行
with open(path, "r+") as f:
for line in islice(f, 7, None):
line.split()
第三步:开始嵌套
y={}
with open(path, "r") as f:
for line in islice(f, 7, None):
#tmax,tmin,sf,rain,sun分别为第一级字典
tma['tmax']=line.split()[2]
tmi['tmin']=line.split()[3]
if line.split()[4] != "None":
a['af']=float(line.split()[4])
else:
a['af']=line.split()[4]
ra['rain']=line.split()[5]
su['sun']=line.split()[6]
#以月份为键,创建第二级字典
#假设解析出来的字典名为dat,那么当访问dat[1853][1]时,应该返回1853年1月所有上述参数
m[int(line.split()[1])]={'tmax':tma['tmax'],'tmin':tmi['tmin'],'af':a['af'],'rain':ra['rain'],'sun':su['sun']}
#以年份为键,创建第三级字典。假设解析出来的字典名为dat,那么当访问dat[1853]时,应该返回1853年12个月的数据
#该级字典不能直接按上面的方法嵌套。例如,1853年5月的数据会覆盖1853年4月的数据
if int(line.split()[0]) not in y.keys(): #如果该年份是第一次出现
y[int(line.split()[0])]={}
y[int(line.split()[0])][int(line.split()[1])]=m[int(line.split()[1])]
else:
y[int(line.split()[0])][int(line.split()[1])]=m[int(line.split()[1])]
return y
第四步:测试输出。
将上面的代码整合到函数Parse()中,返回一个多级字典。
n = int(input())
dat = Parse()
for s in range(n):
cmd = input().split()
y = int(cmd[0])
m = int(cmd[1])
t = cmd[2]
print(dat[y][m][t])
|