Python学习之路第二天——迭代器生成器算法基础
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习之路第二天——迭代器生成器算法基础相关的知识,希望对你有一定的参考价值。
一、迭代器:
迭代器是访问集合元素的一种方式。
迭代器对象是从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。
另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
1、创建一个迭代器:
x = iter([1, 2, 3, 4]) print(x) 以上实例输出结果: <list_iterator object at 0x000000000107C1D0>
2、迭代器操作:
__next__()函数:就是取迭代器内的值: x = iter([1, 2, 3, 4]) print(x.__next__()) print(x.__next__()) print(x.__next__()) print(x.__next__()) print(x.__next__()) 以上实例输出结果: 1 2 3 4 Traceback (most recent call last): File "E:/project/s12/day1/test.py", line 11, in <module> print(x.__next__()) StopIteration 注:当迭代器内的值全部取完后,就会报出如上错误。
二、生成器(yield):
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器。
def cash_out(amount): while amount >0: amount -= 1 yield 1 print("擦,又来取钱了。。。败家子!") ATM = cash_out(3) print("取到钱 %s 万" % ATM.__next__()) print("花掉花掉!") print("取到钱 %s 万" % ATM.__next__()) print("取到钱 %s 万" % ATM.__next__()) 以上实例输出结果: 取到钱 1 万 花掉花掉! 擦,又来取钱了。。。败家子! 取到钱 1 万 擦,又来取钱了。。。败家子! 取到钱 1 万 注:yield函数可以使一个循环执行一半时做别的操作,然后再反回循环继续执行。
作用:
yield的主要效果,就是可以使函数中断,并保存中断状态,中断后,代码可以去执行其他操作,其他操作完成后,还可以再重新调用这个函数,从上次yield的下一句开始执行。
3、yield接收参数:
yield实现在单线程的情况下实现并发运算的效果:
import time def consumer(name): print("%s 准备吃包子啦!" %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name): c = consumer(‘A‘) c2 = consumer(‘B‘) c.__next__() c2.__next__() print("老子开始准备做包子啦!") for i in range(3): time.sleep(1) print("做了2个包子!") c.send(i) c2.send(i) producer("Earl") 以上实例输出结果: A 准备吃包子啦! B 准备吃包子啦! 老子开始准备做包子啦! 做了2个包子! 包子[0]来了,被[A]吃了! 包子[0]来了,被[B]吃了! 做了2个包子! 包子[1]来了,被[A]吃了! 包子[1]来了,被[B]吃了! 做了2个包子! 包子[2]来了,被[A]吃了! 包子[2]来了,被[B]吃了!
三、装饰器:
需求:当我们开发好了一个接口,这个接口是提供给用户使用,但是在使用过程中需要添加一下功能,在不改变接口调用方式与代码的情况下,增加这个功能,怎么办呢?这个时候就需要装饰器上场了。
def login(func): def x (user): if user == ‘earl‘: return func(user) return x @login def tv(name): print(‘欢迎%s,来到电视剧频道‘ %name) tv(‘earl‘) 以上实例输出结果: 欢迎earl,来到电视剧频道
装饰器传递参数实例:
def Before(request): print(‘before‘) def After(request): print(‘after‘) def Filter(before_func,after_func): def outer(main_func): def wrapper(request): before_result = before_func(request) if(before_result != None): return before_result; main_result = main_func(request) if(main_result != None): return main_result; after_result = after_func(request) if(after_result != None): return after_result; return wrapper return outer @Filter(Before, After) def Index(request): print(‘index‘) Index(‘example‘) 以上实例输出结果: before index after
说明:一个函数如果在函数名加上括号例如func()是执行func这个函数,如果不加括号例如func说是取func这个函数的内存id值,不执行函数,在迭代器中很多return调用的是只是函数名。所以在使迭代器中对这个要多注意。
四、递归:
特点
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
1、利用函数编写如下数列:
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368
def func(arg1, arg2): if arg1 == 0: print(arg1, arg2) arg3 = arg1 + arg2 if arg3 < 10: print(arg3) func(arg2, arg3) func(0,1) 以上实例输出结果: 0 1 1 2 3 5 8
2、通过递归实现2分查找:
def binary_search(data_list,find_num): mid_pos = int(len(data_list) /2 ) mid_val = data_list[mid_pos] print(data_list) if len(data_list) >= 1: if mid_val > find_num: print("[%s] should be in left of [%s]" %(find_num,mid_val)) binary_search(data_list[:mid_pos],find_num) elif mid_val < find_num: print("[%s] should be in right of [%s]" %(find_num,mid_val)) binary_search(data_list[mid_pos:],find_num) else: print("Find ", find_num) else: print("cannot find [%s] in data_list" %find_num) if __name__ == ‘__main__‘: primes = list(range(1,20)) binary_search(primes,10) else: print("cannot find [%s] in data_list" %find_num) if __name__ == ‘__main__‘: primes = list(range(1,30)) binary_search(primes,10) 以上实例输出结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] [10] should be in left of [15] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] [10] should be in right of [8] [8, 9, 10, 11, 12, 13, 14] [10] should be in left of [11] [8, 9, 10] [10] should be in right of [9] [9, 10] Find 10
五、基础算法:
生成一个4*4的2维数组并将其顺时针旋转90度
array=[[col for col in range(5)] for row in range(5)] #初始化一个4*4数组 for row in array: #旋转前先看看数组长啥样 print(row) print(‘-------------‘) for i,row in enumerate(array): for index in range(i,len(row)): tmp = array[index][i] array[index][i] = array[i][index] print(tmp,array[i][index]) array[i][index] = tmp for r in array:print(r) print(‘--one big loop --‘) 以上实例输出结果: [0, 1, 2, 3, 4] [0, 1, 2, 3, 4] [0, 1, 2, 3, 4] [0, 1, 2, 3, 4] [0, 1, 2, 3, 4] ------------- 0 0 0 1 0 2 0 3 0 4 [0, 0, 0, 0, 0] [1, 1, 2, 3, 4] [2, 1, 2, 3, 4] [3, 1, 2, 3, 4] [4, 1, 2, 3, 4] --one big loop -- 1 1 1 2 1 3 1 4 [0, 0, 0, 0, 0] [1, 1, 1, 1, 1] [2, 2, 2, 3, 4] [3, 3, 2, 3, 4] [4, 4, 2, 3, 4] --one big loop -- 2 2 2 3 2 4 [0, 0, 0, 0, 0] [1, 1, 1, 1, 1] [2, 2, 2, 2, 2] [3, 3, 3, 3, 4] [4, 4, 4, 3, 4] --one big loop -- 3 3 3 4 [0, 0, 0, 0, 0] [1, 1, 1, 1, 1] [2, 2, 2, 2, 2] [3, 3, 3, 3, 3] [4, 4, 4, 4, 4] --one big loop -- 4 4 [0, 0, 0, 0, 0] [1, 1, 1, 1, 1] [2, 2, 2, 2, 2] [3, 3, 3, 3, 3] [4, 4, 4, 4, 4] --one big loop --
以上是关于Python学习之路第二天——迭代器生成器算法基础的主要内容,如果未能解决你的问题,请参考以下文章