python基础-生成器

什么是生成器

# 知乎链接:https://www.zhihu.com/question/20829330

# 生成器:生成器是一种迭代器,是一种特殊的函数,使用yield操作将函数构造成迭代器。
# 简单概念:函数+yield
# 普通的函数有一般有一个入口,有一个返回值;生成器有多个入口,多个返回值。
# 生成器的作用:延迟器,需要的时候再拿值,适合大数据量处理;节省内存压力

生成器与一般函数比较

# 一般函数与生成器的比较
# 写一个生成器
def hello():
    print("hello")
    yield hello

# 写一个函数
def hello1():
    print("hello1")
    return hello1

h=hello()
print(h)
print(next(h))
print(type(h))
# <generator object hello at 0x10f7bceb8>
# hello
# <class 'generator'>

h1=hello1()
print(h1)
print(type(h1))
# hello1
# <function hello1 at 0x10f7c0b70>
# <class 'function'>


# 太明显了,一般我们打印一个函数名+()就会打印函数执行的结果,是个很明确的结果
# 但是同样是函数名+()打印出来的是一个生成器对象,不是一个明确的结果,要想得到一个明确的结果必需是next(生成器对象obj)

  

from collections import Iterator

def htest():
    print("hello,yield")
    yield ["hekllo",'hh'],["hhh"]
    print("two")
    yield 1,2,3,4
    print("three")
    yield "helo","word","hahh"
    print("four")
    yield 5,6
    print("five")
    yield 5

#g 是什么,g就是生成器对象,iter是可迭代对象所有,next是迭代器所有,方法里就放迭代器里的对象
g=htest()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

#print(next(g))   #超出范围,报错,stopIteraton,我们这里是手动调用,目的在于看清,他能记清楚上次的位置,每次自动输出下一个

# 注意:next()里放的是生成器对象,生成器对象,生成器对象,函数名+()

  

 

生成器举例

def init(func):
    print("hello1")
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        next(res)
        return res

    return wrapper


@init
def eater(name):
    print("name:%s,start to eat"%name)
    food_list=[]
    while True:
        food=yield food_list
        print("%s eat %s"%(name,food))
        food_list.append(food)

    print("done")

e=eater("alex")


e.send("鲍鱼仔")
e.send("鱿鱼仔")
e.send("章鱼仔")
e.send("墨鱼仔")




# 生成器:

# haha=(x**2 for x in range(5))
# print(next(haha))
# print(next(haha))
# print(next(haha))
# print(next(haha))
# print(next(haha))



def gen(n):
    for i in range(n):
        yield i**2

for i in gen(5):
    print(i)



# 如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。
# 好的方法是利用固定长度的缓冲区来不断读取文件内容。
# 通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:



def gen1(n):
    a=[]
    for i in range(n):
        a.append(i**2)
    return a

for i in gen1(5):
    print(i)




posted @ 2017-09-08 19:23  Adamanter  阅读(130)  评论(0编辑  收藏  举报