- 生成器
- 迭代器
- 内置函数
- 作业
一、生成器
1.1、列表生成器
问题引入:看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1
方案一:
a = [1,3,4,6,7,7,8,9,11] for index,i in enumerate(a): a[index] +=1 print(a) 原值修改
方案二:
>>> a [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> a = map(lambda x:x+1, a) >>> a <map object at 0x101d2c630> >>> for i in a:print(i) ... 3 5 7 9 11
方案三:列表生成器
>>> a = [i+1 for i in range(10)] >>> a [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1.2、为什么要有生成器呢?
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
1.3、生成器如何创建
方法一,直接把列表生成器的【】变成():
>>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g <generator object <genexpr> at 0x1022ef630>
可以注意到的是,g不再是一个列表生成器,而是一个generator对象了!!!!
方法二,除了改写列表生成器来构造generator对象之外,还可以用函数实现:
只需要把print-->yield
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return ‘done‘ ################################################## >>> fib(10) 1 1 2 3 5 8 13 21 34 55 done #################################################### def fib(max): n,a,b = 0,0,1 while n < max: #print(b) yield b a,b = b,a+b n += 1 return ‘done‘ ################################################### >>> f = fib(6) >>> f <generator object fib at 0x104feaaa0>
可以看到,函数实现的功能是一样的,就是把print-->yield之后,fib(6)就变成了一个generator对象了,而不是一个普通函数
1.4、如何使用gengrator呢
如果要一个一个打印出来,可以通过next()
函数获得generator的下一个返回值:
g = (x * x for x in range(10)) >>> next(g) 0 >>> next(g) 1 >>> next(g) 4 >>> next(g) 9 >>> next(g) 16 >>> next(g) 25 >>> next(g)
generator保存的是算法,每次调用next(g)
,就计算出g
的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration
的错误
我们创建了一个generator后,基本上永远不会调用next()
,而是通过for
循环来迭代它,并且不需要关心StopIteration
的错误。
>>> g = (x * x for x in range(10)) >>> for n in g: ... print(n) ... 0 1 4 9 16 25 36 49 64 81
1.5、总结+理解难点
def fib(max): n,a,b = 0,0,1 while n < max: #print(b) yield b a,b = b,a+b n += 1 return ‘done‘ data = fib(10) print(data) print(data.__next__()) print(data.__next__()) print("干点别的事") print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) ###################################### #输出 <generator object fib at 0x101be02b0> 1 1 干点别的事 2 3 5 8 13
最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return
语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。在上面fib的例子,我们在循环过程中不断调用yield
,就会不断中断
二、迭代器
- 凡是可作用于
for
循环的对象都是Iterable
类型;凡是可作用于
next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列(生成器一定是迭代器);集合数据类型如
list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
>>> from collections import Iterable >>> isinstance([], Iterable) True >>> isinstance({}, Iterable) True >>> isinstance(‘abc‘, Iterable) True >>> isinstance((x for x in range(10)), Iterable) True >>> isinstance(100, Iterable) False
可以使用isinstance()
判断一个对象是否是Iterator
对象:
>>> from collections import Iterator >>> isinstance((x for x in range(10)), Iterator) True >>> isinstance([], Iterator) False >>> isinstance({}, Iterator) False >>> isinstance(‘abc‘, Iterator)
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
>>> isinstance(iter([]), Iterator) True >>> isinstance(iter(‘abc‘), Iterator) True
三、内置函数
四、作业
作业需求:
模拟实现一个ATM + 购物商城程序
- 额度 15000或自定义
- 实现购物商城,买东西加入 购物车,调用信用卡接口结账
- 可以提现,手续费5%
- 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
- 支持多账户登录
- 支持账户间转账
- 记录每月日常消费流水
- 提供还款接口
- ATM记录操作日志
- 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
- 用户认证用装饰器
原文地址:https://www.cnblogs.com/mesunyueru/p/8970949.html