三周五次课(11月3日) 1.生成式和生成器 2.迭代器 3.装饰器
来源:互联网 发布:vero moda淘宝旗舰店 编辑:程序博客网 时间:2024/05/22 03:27
三周五次课(11月3日)
1. 生成式和生成器
表生成式是python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理。语法格式为:
[exp for val in collection if condition]相当于result=[]for val in collection: if(condition): result.append(exp)
例子,输出1到100的偶数的平方:
a = [x*x for x in xrange(10) if x*x%2 == 0]print(type(a))print(a)结果:<type 'list'>[0, 4, 16, 36, 64]
解释:
1, 以此取出xrange(10)从0到9的数字
2, 判断x*x是偶数,就保留,存在新的字典中
3, 把所有符合x*x是偶数的元素都放到新的列表中返回
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
要创建一个generator,有很多种方法。第一种方法是把一个列表生成式的[]改成(),就创建了一个generator:
生成器是一次生成一个值的特殊类型函数。可以将其视为可恢复函数。调用该函数将返回一个可用于生成连续 x 值的生成器【Generator】,简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候又从上次中断的地方开始执行,而生成器内的所有变量参数都会被保存下来供下一次使用。
要创建一个generator,有很多种方法。
1、第一种方法是把一个列表生成式的[]改成(),就创建了一个generator:
例子:
a = (x*x for x in xrange(10) if x*x%2 == 0)print(type(a))print(a.next())print(a.next())print('aaaaaaa')for i in a:print(i)
结果:
<type 'generator'>04aaaaaaa163664
解释:
generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素为止。类比一下xrange。
2.定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
def fib(n): sum = 0 i = 0 while(i<n): sum = sum +i i+=1 print(sum)fib(10)结果:0136101521283645
解释:
这个程序很简单,就是求0到9所有数字之和,接下来,我们只要稍微改动一下,你看看有什么差别
def fib(n): sum = 0 i = 0 while(i<n): sum = sum +i i+=1 yield sumfor x in fib(10):print(x)print(type(fib(10))) //type为generator结果:0136101521283645<type 'generator'>
结果和上面的结果是一样的,但是有什么不同呢,简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。每当遇到yield关键字的时候,你可以理解成函数的return语句,yield后面的值,就是返回的值。但是不像一般的函数在return后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效,下次从yield下面的部分开始执行。
解释:
1, 以为以上函数有关键字yield,所以生成的是一个生成器。
2, 通过for循环调用生成器,当执行到yield的时候,返回sum的值,sum为0,此时暂停并记录sum的值
3, 打印sum的值,然后继续往下执行。此时跳入下一个循环while(1<10)
4, 直到遇到yield的时候,返回sum的值。
5, 反复执行3,4步骤,知道循环结束,最终程序退出
二者的区别很明显:
一个直接返回了表达式的结果列表, 而另一个是一个对象,该对象包含了对表达式结果的计算引用, 通过循环可以直接输出
生成器不会一次性列出所有的数据,当你用到的时候,在列出来,更加节约内存的使用率。
2. 迭代器
Iterable(可迭代对象) 和 Iterator(迭代器) 主要区别是 :
凡是可以用 for 循环的 都是 Iterable(可迭代对象) 凡是需要通过next()函数获得值的可迭代对象都是 Iterator(迭代器)。
(所以生成器可以 被next()函数调用并不断返回下一个值的对象称为迭代器 ) (可以简单理解为生成器 就是 迭代器的可迭代对象)
凡是可作用于for循环的对象都是Iterable类型;例如list,tuple,dict,生成式
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
练习题:用函数实现9*9乘法口诀
l=str()for i in xrange(1,10): for j in xrange(1,i+1): x=('{0}*{1}={2} '.format(j,i,i*j)) l+=x if i == j : l+='\n'print(l)
输出
1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
- 三周五次课(11月3日) 1.生成式和生成器 2.迭代器 3.装饰器
- 二周五次课(10月27日)
- 生成式和生成器 、迭代器、装饰器
- 三周四次课(11月2日) 1. 高阶函数 2. 匿名函数
- 三神器-迭代器、生成器和装饰器
- 三周三次课(11月1日)
- 六周五次课(11月24日) 13.1 NoSQL简介 13.2 redis服务搭建 13.3 redis连接池 13.4 redis管道
- 八周五次课(12月15日) 16.1 多进程的消息队列 16.2 消息队列pipe
- 三周一次课(10月30日)
- 2012年3月30日 周五
- python学习-Day15-python生成式和生成器、迭代器、装饰器
- 七周五次课(12月8日) 14.1 多进程多线程概念 14.2 多进程 14.3 多进程实例
- 12月22日 周五
- Python之装饰器、迭代器和生成器
- 二周五次课
- 装饰器,生成器,迭代器
- 装饰器、迭代器、生成器
- 迭代器 生成器 装饰器
- NSSortDescriptor作用
- Java(Eclipse)报出异常java.net.MalformedURLException: no protoco的l解决方法
- HTML部分基础总结(6)
- 中夜之思
- 【变治法】霍纳法则C++代码实现,求一个多项式在一个给定点的值
- 三周五次课(11月3日) 1.生成式和生成器 2.迭代器 3.装饰器
- 工厂模式
- 大数据集群之CDH版本搭建完整版
- 浅谈Java中的equals和==
- java:jsonp前后端实例演示
- java 设计模式之单例模式
- bzoj 4034(树链剖分)
- 5G:非正交多址接入(NOMA)与串行干扰删除(SIC)
- Android秋招面经