1、字典
在上一篇中我们看到数据处理似乎并不是很难的事情,但我们考虑的只是非常简单的情形,所有数据都可以转为同一类型处理。实际中,会有一些文件包含各种类型的数据,而且数据具有结构性,这时候用列表处理数据就不太方便了,比如:
>>> with open('james2.txt') as jaf2:
data=jaf2.readline()
print(data)
James Lee,2002-3-14,2-34,3:21,2.34,2.45,3.01,2:01,2:01,3:10,2-22,2-01,2.01,2:16
我们看到,数据第一项是名字,第二项是生日,之后是跑步成绩。我们将如何构建数据的关联性呢?我们先来看一下字典的用法:
#以下两种方式都可以创建空字典
>>> cleese={}
>>> palin=dict()
>>> type(cleese)
>>> type(palin)
#以下两种方式都可以将键与值关联
>>> cleese['Name']='John Cleese'
>>> cleese['Occupations']=['actor','comedian','writer','film producter']
>>> palin={'Name':'Michael Palin','Occupations':['comedian','actor','writer','tv']}
>>> cleese['Name']
'John Cleese'
>>> cleese['Occupations'][-1]
'film producter'
然后我们用字典来找出运动员前三快的成绩:
>>> def get_coach_data(filename):
try:
with open(filename) as f:
data=f.readline()
templ=data.strip().split(',')
return({'Name':templ.pop(0),
'Dob':templ.pop(0),
'Times':str(sorted(set([sanitize(t) for t in templ]))[0:3])})
except IOerror as err:
print('File error: '+str(err))
return(None)
>>> james=get_coach_data('james2.txt')
>>> print(james['Name']+" 's fastest times are: "+james['Times'])
James Lee 's fastest times are: ['2.01', '2.16', '2.22']
2、类
Python使用class创建对象。每个类都有一个特殊方法,名为__init__(),可以通过这个方法控制如何初始化对象。另外,类中所有方法的第一个参数都是self,实际上self标识了要处理的对象实例。我们依然以运动员为例:
>>> class Athlete:
def __init__(self,name,dob=None,times=[]):
self.name=name
self.dob=dob
self.times=times
def top3(self):
return(sorted(set([sanitize(t) for t in self.times]))[0:3])
>>> def get_coach_data(filename):
try:
with open(filename) as f:
data=f.readline()
templ=data.strip().split(',')
return(Athlete(templ.pop(0),templ.pop(0),templ))
except IOError as err:
print('File error: '+str(err))
return(None)
>>> james=get_coach_data('james2.txt')
>>> print(james.name+" 's fastest times are: "+str(james.top3()))
James Lee 's fastest times are: ['2.01', '2.16', '2.22']
有了类,我们还可以很方便的做很多其它的事,比如我现在有新的跑步成绩数据需要加入,那么我们就可以通过为类增加一个方法来解决:
>>> class Athlete:
def __init__(self,name,dob=None,times=[]):
self.name=name
self.dob=dob
self.times=times
def top3(self):
return(sorted(set([sanitize(t) for t in self.times]))[0:3])
def add_times(self,time):
self.times.extend(time)
>>> vere=Athlete('Vere Vi')
>>> vere.add_times(['1.31','1-21','2.22','2.25'])
>>> print(vere.top3())
['1.21', '1.31', '2.22']
这样看来,我们有什么新的需求,在类中添加新方法就万事大吉了,然而我们看一下add_times方法,它本质上就是列表的extend()方法啊,我们这里还要重新写一遍,不能直接用吗?这就涉及到偷懒的办法:继承。实际上如果我们的类是现有类(比如list)的继承,那么继承类可以直接使用父类所有方法,这非常方便。
#新类派生括号中的类
>>> class AthleteList(list):
def __init__(self,name,dob=None,times=[]):
list.__init__([])
self.name=name
self.dob=dob
self.extend(times)
def top3(self):
#这里self.times变成了self,因为self本身就是计时数据列表
return(sorted(set([sanitize(t) for t in self]))[0:3])
>>> vere=AthleteList('Vere Vi')
>>> vere.extend(['1.31','1-21','2.22','2.25'])
>>> print(vere.top3())
['1.21', '1.31', '2.22']
通过继承我们可以直接使用list类的方法extend()来操作我们的AthleteList对象了,不止如此,我们还可以用列表的其它方法。