1、迭代器&生成器

列表生成式

现在有个需求,列表[1,2,3,4,5,6,7,,8,9],要求把列表里的每个值加1,如何实现?

方法一:

list = [1,2,3,4,5,6,7,8,9]

for index,i in enumerate(list):
list[index] = i + 1 print(list)
运行结果:
[2, 3, 4, 5, 6, 7, 8, 9, 10]

 方法二:

list = [1,2,3,4,5,6,7,8,9]
#map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 列表list,并通过把函数 f 依次作用在 list 的每个元素上,
# 得到一个新的 list 并返回
a = map(lambda x:x+1,list)
for i in a:
print(i)
运行结果:
[2, 3, 4, 5, 6, 7, 8, 9, 10]

 其实,还有一种写法

list = [1,2,3,4,5,6,7,8,9]
a = [x+1 for x in list]
print(a)
运行结果:
[2, 3, 4, 5, 6, 7, 8, 9, 10]

 这就叫做列表生成式

 生成器

通过列表生成式,我们可以创建一个列表,但是,受到内存限制,列表容量是有限的。而且,创建一个包含100百万元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间就白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可在循环过程中不断推算出后面的元素呢?这样就不需创建完整的列表,从而节省大量空间。在python中,这种一边循环一边计算的机制,称为生成器:generator。创建一个generator,有很多中方法,第一种方法很简单,只要把列表生成式中的[]改成(),就创建了一个generator。

a = [x+1 for x in range(10)]
print(a)
a = (x+1 for x in range(10))
print(a)
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
<generator object <genexpr> at 0x0000017258EF2830>

 generator要打印出来,需要通过next()函数获得generator的返回值

print(next(a))
1
print(next(a))
2

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象:

for i in a:
print(i)

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ..

斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a,b=b,a+b
n +=1
return 'done' fib(10)

  

仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:

def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b
n +=1
return 'done'

  这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。yield相当于一个断点

f = fib(10)
print(f.__next__())
print(f.__next__())
print("干点别的事")
print(f.__next__())
print(f.__next__())
运行结果:
1
1
干点别的事
2
3

  同样的,把函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

for i in fib(10):
print(i)

  迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

个人理解:生成器就是迭代器

3、装饰器

软件开发原则:开放-封闭,不能改变原代码的调用方式。

  • 封闭:已实现的功能代码块不应该被修改
  • 开放:对现有功能的扩展开放

闭包函数:python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

 import time
def timer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)#执行index原始函数
stop_time = time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper @timer #index=timer(index)
def index(msg):
print('in the index: ',msg)
return 1
res=index('hello world') #wrapper('hello world')
print(res)
# 装饰器执行流程:
# 1、导入time模块
# 2、定义timer函数,函数名作为变量名赋值给timer函数
# 3、@timer index赋值给timer函数
# 4、定义闭包函数wrapper,直接返回wrapper
# 5、定义index函数
# 6、执行index函数,实际是执行timer函数的返回值wrapper函数

有参装饰器

python之路6-迭代器、生成器、装饰器的更多相关文章

  1. python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

    生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...

  2. Python基础-迭代器&生成器&装饰器

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...

  3. Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

    本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...

  4. 迭代器/生成器/装饰器 /Json & pickle 数据序列化

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  5. 4.python迭代器生成器装饰器

    容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...

  6. python中的迭代器&&生成器&&装饰器

    迭代器iterator 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外, ...

  7. Python学习——迭代器&生成器&装饰器

    一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...

  8. Python 全栈开发五 迭代器 生成器 装饰器

    一.迭代器 迭代协议:对象必须提供一个next方法,执行该方法后会返回迭代的下一项或者抛出Stopiteration异常,终止迭代.切只能往前,不能倒退. 可迭代对象:遵循迭代写一点对象就是可迭代对象 ...

  9. python中的迭代器 生成器 装饰器

    什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,_ ...

  10. Python迭代器&生成器&装饰器

    1. 迭代器 1.1 可迭代对象(Iterator) 迭代器协议:某对象必须提供一个__next__()方法,执行方法要么返回迭代中的下一项,要么引起一个Stopiteration异常,以终止迭代(只 ...

随机推荐

  1. 微信小程序---require()

    我们可以通过require()来获取其它文件导出的数据,但要注意的是传给require的路径只能是相对路径. // 获取指定页面通过module.exports导出的数据 var postsData ...

  2. 下载Dynamics 365 Customer Engagement 工具

    微软动态CRM专家罗勇 ,回复312或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 从Dynamics ...

  3. 【AO笔记】Addins的Toolbar 添加一条分割线

    在XAML中,给Item标签添加separator属性,需要从哪里打分割线,就将其设置为true即可.如下图所示: 如紫色框住的灰色竖线所示. 默认separator属性是false的,这个小东西极其 ...

  4. PHP实现开心消消乐的算法示例

    本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述:      1.在一个8*8的矩阵方格中随机 ...

  5. Typora 快捷键

    今天学习了一下这个工具.很轻便,很好用的. 无序列表:输入-之后输入空格 有序列表:输入数字+“.”之后输入空格 任务列表:-[空格]空格 文字 标题:ctrl+数字 表格:ctrl+t 生成目录:[ ...

  6. c/c++ 重载运算符 ==和!=的重载

    重载运算符 ==和!=的重载 问题:假如有一个类似于vector的类,这个类只能存放string,当有2个这个类的对象时,如何比较这2个对象. 自己重载==和!= 代码(重载==,!=) #inclu ...

  7. 理解ECS的概念和Unity中的ECS设计

    组合优于继承 ecs的概念很早就有了,最初的主要目的应该还是为了改善设计. e-c-s三者都有其意义,e-c是组合优于继承,主要用以改善oo的继承耦合过重以及多继承菱形问题. oop常见设计里,每个g ...

  8. spring boot 中使用 jpa以及jpa介绍

    1.什么是jpa呢?JPA顾名思义就是Java Persistence API的意思,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.12.jpa具有什么 ...

  9. (转载)最完整的自动化测试流程:Python编写执行测试用例及定时自动发送最新测试报告邮件

    今天笔者就要归纳总结下一整套测试流程,从无到有,实现零突破,包括如何编写测试用例,定时执行测试用例,查找最新生成的测试报告文件,自动发送最新测试报告邮件,一整套完整的测试流程.以后各位只要着重如何编写 ...

  10. 3星|《HBO的内容战略》:HBO与美国电视业大事记

    HBO的内容战略 基本是HBO与美国电视业的大事记.从电视的诞生讲起.HBO在1972年首播,1975年做出一个当时惊世骇俗的决定:勇卫星实时向全美发送信号,随即成为覆盖全国的电视台:80年代受到录像 ...