博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python生成器
阅读量:5336 次
发布时间:2019-06-15

本文共 2235 字,大约阅读时间需要 7 分钟。

生成器就是一个可迭代对象

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

 

生成器创建1

s=(i for i in range(5))

生成器创建2

def foo():    yield 1print(foo()) #
|加括号说明执行生成器 print(foo) #
|不加括号说明执行函数
 

 

生成器的使用next方法

def foo():    print(1)    yield 1    #第一个next进来,发现yield后类似return返回值并退出    print(2)    yield 2    #第二个next进来,发现yield后类似return返回值并退出
f=foo() print(next(f))
print(next(f))
print(next(f))  #没有yield所以报错StopIteration 改进:
def foo():    print(1)    yield 1    #第一个next进来,发现yield后类似return返回值并退出    print(2)    yield 2    #第二个next进来,发现yield后类似return返回值并退出
 
f=foo() for i in f:   #说明f是可迭代对象,会自动调用next,遇到StopIteration会自动退出
  print(i)

所以,我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

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

 

可迭代对象:拥有iter方法

list

tuple

dict

string

 

斐波那契数列

用函数实现:

1 def fib(max):2     n, a, b = 0, 0, 13     print(a)4     while n < max:5         print(b)6         a, b = b, a + b7         n = n + 18     return 'done'

 

用列表生成式yield实现

 
def fib(max):     n, a, b = 0, 0, 1     print(a)     while n < max:         yield b      #yield保存了上次执行的地点         a, b = b, a + b         n = n + 1     return 'done' f=fib(5) for i in f:     print(i)
 

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

send赋值

1 def foo(): 2     print('a')  #这儿是第一次next进来输出的 3     t1=yield 1  #遇到yield就像遇到return一样,退出返回值 4     print('b') 5     t2=yield 2 6  7 f=foo() 8 next(f)  #send第一次必须有一个next让他进门 9 #f.send(None)==next(f)10 ret=f.send('aa')     #这里的aa会赋值给t111 print(ret)

 

yield实现在单线程的情况下实现并发运算的效果

import timedef customs(n):    print('%s准备吃包子了'%n)    while True:        baozi=yield        print('%s吃了包子%s'%(n,baozi))def boss(z):    a=customs('a')    b=customs('b')    next(a)    next(b)    print('%s开始做包子了!'%z)    for i in range(10):        time.sleep(1)        print('包子做好了!')        a.send(i)        b.send(i)boss('xiaoyaz')

 

转载于:https://www.cnblogs.com/xiaoyaz/p/7620547.html

你可能感兴趣的文章
线程安全问题
查看>>
SSM集成activiti6.0错误集锦(一)
查看>>
下拉刷新
查看>>
linux的子进程调用exec( )系列函数
查看>>
MSChart的研究
查看>>
C# 索引器
查看>>
MySQLdb & pymsql
查看>>
zju 2744 回文字符 hdu 1544
查看>>
delphi 内嵌汇编例子
查看>>
【luogu P2298 Mzc和男家丁的游戏】 题解
查看>>
前端笔记-bom
查看>>
MATLAB作图方法与技巧(一)
查看>>
上海淮海中路上苹果旗舰店门口欲砸一台IMAC电脑维权
查看>>
Google透露Android Market恶意程序扫描服务
查看>>
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
eclipse-将同一个文件分屏显示
查看>>
对闭包的理解
查看>>