关于python的开发环境配置,请看我之前的博客:
当然初学者可以使用IDLE的shell来编写代码,对于初学者来说很好用。
第一部分列表
给一个创建名为movies列表的例子:
movies = ['The Holy Grail',1975,'The life of Brian',1979,'The Meaning of Life',1983]
列表常用的BIF(BIF指内置函数):
- print()BIF的作用:在屏幕上显示列表内容
- len()BIF的作用:得出列表中有多少数据项
列表常用的方法:
- append()方法的作用:在列表末尾增加一个数据项
- pop()方法的作用:从列表末尾删除数据
- extend()方法的作用:在列表末尾增加一个数据项集合
- remove()方法的作用:在列表中找到并删除一个特定的数据项
- insert()方法的作用:在某个特定的位置前面增加一个数据项
附一张具体使用的示例:
for循环处理任意大小的列表:
for 目标标识符 in 列表:
列表处理代码
示例:
划重点:
1.python的变量标识符没有类型。
2.在同一个列表中可以存储任意类型的数据。
3.在python中创建一个列表时,解释器会在内存中创建一个类似数组的数据结构来存储数据,数据项自下而上堆放(形成一个堆栈),堆栈中的第一个槽编号是0,第二个槽编号是1,第三个槽编号是2,以此类推。所以使用print(movies[1])访问某一个数据项。
4.当然在列表中可以嵌套列表,用if_else或者用isinstance函数来判断每一项是否为列表。
5.for循环允许迭代处理一个列表,这通常比使用一个等价的while循环更方便。
第二部分函数
Python中的函数是一个命名的代码组,如果需要,还可以有一个参数表(可选)。要用def语句定义python函数,为函数提供一个函数名,并在括号里指定一个参数表,参数表可以为空。
以下是定义函数的标准形式:
def 函数名(参数):
函数代码组
示例:显示带有嵌套列表的列表内容,要求功能中可以选择是否缩进,显示结果整体从左边缩进多少位和可选的结果输出位置。
def print_lol(the_list, indent=False, level=0, out=sys.stdout):
for each_item in the_list:
if isinstance(each_item, list):
level =level + 1
print_lol(each_item, indent, level, out)
level = level - 1
else:
if indent:
# 使用level的值来控制使用多少个制表符
for tab_stop in range(level):
print('\t', end='', file=out)
print(each_item, file=out)
示例代码中indent,level,out都有缺省值,使用这个函数可以自己指定参数,也可以直接使用缺省值。indent代表是否使用缩进,默认是不使用缩进。level代表结果整体从左边缩进多少位,默认是0,也就是整体是从左边起始位置开始缩进的。out代表结果输出位置,默认是标准输出。
常用的BIF说明:
划重点:
为了增强代码的健壮性,一般定义函数时都会给参数设置缺省值,如果定义函数时为函数参数提供一个缺省值,这个函数参数就是可选的。
第三部分处理在文件中的数据
python中的基本输入机制都是基于行的:从文本文件向程序读入数据时,一次会到达一个数据行。
示例:文件去http://python.itcarlow.ie/resources.html下载Chapter 3 & 4: sketch.txt,处理文件的数据并从数据中抽取出两个人说的话,并打印出来。
"""
处理一个文本文件,将整理Man和Other Man说的全部的话,然后打印出来。
"""
# 用"try/except"这里指定了IOError,是为了避免读取数据时产生错误的情况
try:
# 打开一个文件,传入的参数是文件在电脑里存放的路径
data = open('D:\\pythondata\\HeadFirstPython\\chapter3\\sketch.txt')
# python是一行一行读取的,所以要迭代
for each_line in data:
# 用"try/except"这里指定了ValueError,是为了避免分隔数据时产生数据和分隔符不匹配的情况
# pass的意思就是忽略这样的错误,代码继续执行
# split(':',1)是为了处理一行文本中有两个冒号的情况,我们只以第一个冒号作为分隔符
try:
(role,line_spoken)=each_line.split(':',1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
except ValueError:
pass
data.close()
except IOError:
print('The data file is missing!')
划重点:
1.使用”try/except”可以让你关注代码真正需要做的工作,而且可以避免向程序增加不必要的代码和逻辑。
2.数据不符合期望的格式时会出现ValueError。
3.数据无法正常访问时会出现IOError(例如你的数据文件已经被移走或者重命名)。
4.pass语句就是python的空语句或null语句,它什么也不做。
第四部分将数据保存到文件
使用open()BIF打开文件时,可以指定使用什么访问模式。默认地,open()使用模式r表示读,所以不需要专门指定r模式。
使用访问模式w时,python会打开指定的文件来完成写。如果这个文件已经存在,则会清空它现有的内容,也就是完全清除。要追加到一个文件,需要使用访问模式a。要打开一个文件来完成写和读(不清除),需要使用w+。如果想打开一个文件完成写,但是这个文件并不存在,那么首先会为你创建这个文件,然后再打开文件进行写。
示例:还是读取sketch.txt,然后将输出文件分别命名为man_data.txt(存储一个人讲的话)和other_data.txt(存储另一个人讲的话)。数据文件打开后都要确保将其关闭。
man = []
other = []
try:
data = open('D:\pythondata\HeadFirstPython\chapter3\sketch.txt')
for each_line in data:
try:
(role,line_spoken)=each_line.split(':',1)
line_spoken=line_spoken.strip()
if role == 'Man':
man.append(line_spoken)
elif role == 'Other Man':
other.append(line_spoken)
except ValueError:
pass
except IOError:
print('The datafile is missing!')
finally:
data.close()
try:
man_file = open('D:\pythondata\HeadFirstPython\chapter3\man_data.txt','w')
other_file = open('D:\pythondata\HeadFirstPython\chapter3\other_data.txt','w')
print(man, file= man_file)
print(other, file=other_file)
except IOError:
print('File error.')
finally:
man_file.close()
other_file.close()
“腌制”数据
python提供了一个标准库,名为pickle,它可以保存和加载几乎所有python数据对象,包括列表。
使用pickle的方法:导入pickle模块,然后使用dump()保存数据,以后某个时间使用load()恢复数据。处理腌制数据时的唯一要求是必须以二进制访问模式打开这些文件。
示例:将[1,2,’three’]保存数据,然后再恢复数据。
import pickle
# “b”告诉python以二进制模式打开数据文件
with open('mydata.pickle','wb') as mysavedata:
pickle.dump([1,2,'three'],mysavedata)
with open('mydata.pickle','rb') as myrestoredata:
a_list = pickle.load(myrestoredata)
print(a_list)
划重点:
1.不论出现什么错误都必须运行某些代码,比如关闭文件的代码,可以向try语句的finally组增加代码。
2.with语句会自动处理所有已打开文件的关闭工作,即使出现异常也不例外。with语句也使用as关键字。
3.print()BIF的file参数控制将数据发送/保存在哪里。
4.标准库的pickle模块允许你将python数据对象保存到磁盘以及从磁盘恢复。pickle.dump()函数将数据保存到磁盘,pickle.load()函数从磁盘恢复数据。
“腌制”数据时,“腌制”代表将数据对象保存到一个持久存储的过程。“解除腌制”代表从持久存储中恢复一个已保存的数据对象的过程。
第五部分处理数据
排序有两种方式:
1.原地排序
原地排序是用排序后的数据替换原来的数据。对于列表,sort()方法会提供原地排序。
2.复制排序
复制排序是原数据的顺序依然保留,只是对一个副本排序。在python中,sorted()BIF支持复制排序。
默认地,sort()方法和sorted()BIF都会按升序对数据排序。要以降序对数据排序,需要向sort()或sorted()传入参数reverse=True,python会负责具体处理。
示例:文件去http://python.itcarlow.ie/resources.html下载Chapter 6 updated TXT files 。处理文件中运动员的计时数据,要把错误数据进行转换,并显示一个运动员的最快的前三个时间。
"""
这个函数的功能是找到错误数据,替换成正确数据。
"""
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return time_string
(mins, secs) = time_string.split(splitter)
return mins+'.'+secs
"""
这个函数的功能是读取文件中的数据,返回的是一个运动员的信息(用字典来存储数据)和一个运动员跑步最快的前三个时间的信息。
"""
def data_control(file_path):
try:
file_content = []
with open(file_path) as read_file:
data = read_file.readline()
file_content = data.strip().split(',')
sarah_data = {'sarah_name': file_content.pop(0), 'sarah_dob': file_content.pop(0), 'sarah_time': file_content}
fastest_time = str(sorted(set([sanitize(t) for t in sarah_data['sarah_time']]))[0:3])
return sarah_data,fastest_time
except IOError as ioerr:
print('File error: '+str(ioerr))
return(None)
sarah = data_control('D:\pythondata\hfpy_ch6_data\sarah2.txt')
print(sarah[0]['sarah_name']+"'s fastest time are:"+sarah[1])
划重点:
1.列表推导:用很少的代码量来完成列表的转换。
clean_mikey=[]
for each_t in mikey:
clean_mikey.append(sanitize(each_t))
转换为
clean_mikey=[sanitize(each_t) for each_t in mikey]
2.用集合删除重复项
python提供了集合数据结构,集合最突出的特性是集合中的数据项是无序的,而且不允许重复。创建空集合时可以使用set()BIF,如果想一步完成集合的创建和填充,可以指定一个现有列表作为set()BIF的参数。
3.sarah_data = {‘sarah_name’: file_content.pop(0), ‘sarah_dob’: file_content.pop(0), ‘sarah_time’: file_content}这一句代码使用到了字典。在python中,除了之前我们提到过的列表和集合以外,python还提供了字典,字典是一个python内置的数据结构,允许将数据与键而不是与数字关联。这样可以使内存中的数据与实际数据的结构保持一致。
第六部分定制数据对象
当python的内置数据结构无法胜任时,Python class语句还允许你定义自己的数据结构。Python遵循标准的面向对象编程模型,提供了一种方法允许将代码及其处理的数据定义为一个类。一旦有了类定义,就可以用它来创建(或实例化)数据对象,它会继承类的属性。在面向对象世界里,你的代码通常称为类的方法,而数据通常称为类的属性。实例化的数据对象通常称为实例。
示例:文件去http://python.itcarlow.ie/resources.html下载Chapter 6 updated TXT files 。编写代码定义Athlete类,除了init()方法外,还要定义一个新方法top3(),调用这个方法会返回最快的3个时间。同时调整get_coach_data()函数,返回一个Athlete对象而不是字典。
class Athlete:
def __init__(self,a_name,a_dob,a_times):
self.name = a_name
self.dob = a_dob
self.times= a_times
def top3(self):
return (sorted(set([sanitize(t) for t in self.times]))[0:3])
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return time_string
(mins, secs) = time_string.split(splitter)
return mins+'.'+secs
def get_coach_data(file_path):
try:
with open(file_path) as read_file:
data = read_file.readline()
templ = data.strip().split(',')
return (Athlete(templ.pop(0),templ.pop(0),templ))
except IOError as ioerr:
print('File error: '+str(ioerr))
return(None)
james = get_coach_data('D:\pythondata\hfpy_ch6_data\james2.txt')
print(james.name+"'s fastest times are:"+str(james.top3()))
划重点:
Python使用class创建对象。每个定义的类都有一个特殊的方法,名为init(),可以通过这个方法控制如何初始化对象。
类中的方法与函数的定义很类似,也就是说,同样使用def来定义。基本形式如下:
class Athlete:
def __init__(self):
#The code to initialize a "Athlete" object.#
“init”前面和后面分别有两个下划线。
每个方法的第一个参数都是self,使用self标识调用对象实例。
事实上,Athlete类与Python列表的区别只是Athlete类包含name和dob对象属性。Python的class允许你从零开始创建一个定制类,就像创建Athlete类那样。不过,class还允许通过继承现有的其他类来创建一个类,这也包括用list、set和dict提供的Python内置数据结构类。
示例:重写Athlete类,让它继承内置的list类,将这个新类命名为AthleteList。
# 提供一个类名list,新类将派生这个类。
class AthleteList(list):
def __init__(self,a_name=None,a_dob=None,a_times=[]):
# 初始化所派生的类,然后把参数赋值属性。
list.__init__([])
self.name = a_name
self.dob = a_dob
self.extend(a_times)
def top3(self):
return (sorted(set([sanitize(t) for t in self]))[0:3])
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return time_string
(mins, secs) = time_string.split(splitter)
return mins+'.'+secs
def get_coach_data(file_path):
try:
with open(file_path) as read_file:
data = read_file.readline()
templ = data.strip().split(',')
return (AthleteList(templ.pop(0),templ.pop(0),templ))
except IOError as ioerr:
print('File error: '+str(ioerr))
return(None)
james = get_coach_data('D:\pythondata\hfpy_ch6_data\james2.txt')
print(james.name+"'s fastest times are:"+str(james.top3()))
划重点:
1.“字典”,这是一个内置的数据结构,允许将数据值与键关联。
2.“self”,这是一个方法参数,总是指向当前对象实例。
3.使用dict()工厂函数或使用{}可以创建一个空字典。
4.要访问一个名为person的字典中与键Name关联的值,可以使用我们熟悉的中括号记法:person[‘Name’]
5.类方法(代码)与函数的定义基本相同,也就是说,要用def关键字定义。