本章内容
- 迭代器生成器
- 递归算法
- 正则
- 异常处理
一、迭代器、生成器
在说迭代器之前,我们先回顾一下可迭代对象。我们说可迭代对象就是能够用for循环遍历的对象。然后来说迭代器了,那这么说,可迭代对象和迭代器名字里面都有个迭代,两者之间有什么联系呢?
for循环的原理,当我们用for循环来遍历一个对象时,for循环首先做了一连串这样的事情:判断这个对象是否是可迭代对象,如果是 --->> 利用iter方法将这个对象变成一个iterator(迭代器) --->> 然后一直调用 __next__ 方法,一步一步的将对象中的元素遍历而出。
那么问题来了,什么是迭代器?
迭代器:迭代器是访问集合元素(即存在多个元素)的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能前进不能后退。迭代器不要求事先准备好整个迭代过程中的元素。迭起器仅仅再迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。所以迭代器特别适合用来遍历一些非常巨大或者是无限的集合。
特点:
- 访问者不需要关心迭代器内部的结构,仅使用__next__()方法就可以不断的取下一个内容
- 不能指定访问集合中的某个值,只能从头到尾。走到哪生成到哪
- 访问无法后退
- 用来遍历巨大集合可以节省内存
1 a = iter([1,2,3,4,5]) 2 # 生成一个迭代器 3 4 print(a.__next__()) 5 # 从第一个元素开始取 6 7 print(a.__next__()) 8 print(a.__next__()) 9 print(a.__next__()) 10 print(a.__next__()) 11 #取到最后一个了 12 13 print(a.__next__()) 14 # 当没有元素可取时,抛出StopIteration错误
生成器:一个函数调用后返回一个迭代器(使用__next__()取值),那这个函数就是一个生成器。
1 def func(): 2 3 ''' 4 代码块 5 ''' 6 7 yield 8 #使函数中断并保存中断状态 9 10 print(func()) 11 # 打印结果:<generator object func at 0x000001B4415E5888>
从打印结果中我们可以看到返回了一个 generator object ,即一个生成器对象。
yield:yield后面的值即为返回值。yield会中断函数的执行并记录中断位置,等下次重新调用这个函数时,就会接着上次继续执行。
利用生成器做一个range(2.x中的xrange)的功能
1 def range(n): 2 # 创建生成器函数名 3 4 start = 0 5 # 从0开始 6 7 while start < n: 8 # 创建循环 9 10 yield start 11 # 返回start,执行后结束,保存执行完的状态 12 13 start += 1 14 # 下次调用执行 15 16 obj = range(5) 17 print(obj.__next__()) 18 # 利用__next__()调用 19 print(obj.__next__()) 20 print(obj.__next__()) 21 print(obj.__next__()) 22 print(obj.__next__())
二、递归算法
递归算法是一种直接或者间接地调用自身算法的过程(递归函数就是一个体现)。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简介而且易于理解。
特点:
- 递归就是再过程或函数里调用自身。
- 再使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
- 递归算法解题通常显得很简洁,但递归算法解题的运行效率低。
- 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
要求:
- 每次调用在问题规模上都有所减少(通常是减半)
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)
- 再问题的规模极小时必须要直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归条用将会称为死循环而不能正常结束。
实例:上一篇中有是实现斐波那契数列的实例(并没有详细说明递归)。用Alex老师写的二分法
1 def binary_search(data_list,find_num): 2 mid_pos = int(len(data_list) /2 ) #find the middle position of the list 3 mid_val = data_list[mid_pos] # get the value by it's position 4 print(data_list) 5 if len(data_list) >1: 6 if mid_val > find_num: # means the find_num is in left hand of mid_val 7 print("[%s] should be in left of [%s]" %(find_num,mid_val)) 8 binary_search(data_list[:mid_pos],find_num) 9 elif mid_val < find_num: # means the find_num is in the right hand of mid_val 10 print("[%s] should be in right of [%s]" %(find_num,mid_val)) 11 binary_search(data_list[mid_pos:],find_num) 12 else: # means the mid_val == find_num 13 print("Find ", find_num) 14 15 else: 16 print("cannot find [%s] in data_list" %find_num) 17 18 if __name__ == '__main__': 19 primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 20 binary_search(primes,67)
三、正则
正则表达式:正则表达式并是在各个编程语言都有的一种用于处理字符串的强大工具。
特点:使用正则处理字符串在效率上可能不如str自带的方法,但是它的功能十分强大,所以python当然也提供了正则表达式即re模块。
匹配方法:
准备以后整理用MarkDown来了,以后推送到github上咯点下面
四、异常处理