day12

生成器:就是自己用python代码写的迭代器,生成器的本质就是迭代器

l1 = [1, 2, 3]
iter1 = iter(l1)
print(iter1)         #<list_iterator object at 0x00000247A62CDDD8>

用以下方式构建一个生成器:

1.通过生成器函数

2.生成器表达式

def func1(x):
    x += 1
    print(111)
    print(222)
    print(333)
    yield x
    x += 2
    print(666)
    yield 'ake'
    x += 3
    yield 4
    print(345)
d = func1(5)          #生成器函数的对象
# print(d)              #<generator object func1 at 0x0000021EF9F5E938>  生成器函数的地址
print(d.__next__())    #111  222   333  6
print(d.__next__())     #666   ake   因为yield没有返回x += 2 的值,所以打印的没有x
print(d.__next__())     #ake  4
print(d.__next__())     #打印出345,但是报错

一个next 对应一个yield ,yield 将值返回给生成器对象。__next__()

yield跟return的区别:

return 结束函数,并将值返回给函数的执行者

yield 不会结束函数,一个next 对应yield,给生成器对象.__next__()返回值

生成器函数 vs 迭代器

区别1:自定制的区别

l1 = [1,2,3,4,5]
l1.__iter__()             #迭代器



def func1(x):             #生成器
    x += 1
    yield x
    x += 2
    yield x
    x += 3
    yield 4
g1 = func1(5)
print(g1.__next__())  #6
print(g1.__next__())  #8
print(g1.__next__())  #4

区别2:内存级别的区别

迭代器是需要可迭代对象进行转化,从本质就节省内存

生成器直接创建,不需要转化,从本质就节省内存

def func1():
    for i in range(1,10000):
        yield i
g1 = func1()
for i in range(50):
    print(g1.__next__())         #打印的是1-50
for i in range(50):
    print(g1.__next__())         #打印的是51-100 

每循环五十个,就打印五十个,非常节省内存

send 与 next 的区别:

def func1():
    count = yield 6   
    print(count)
    count1 = yield 7           
    print(count1)
    yield 8
g = func1()
#next(g)                  
#g.send('ake')
#next(g)
print(next(g))         #这个next执行第一个yield 6
print(g.send('ake'))  #send把值传给上一个yield,count = ‘ake’ 然后执行yield 7,count没有值,所以是None     
print(next(g))      #这个next执行的是yield 8  

send 与 next一样,也是对生成器取值(执行一个yield)方法

send 可以给上一个yield传值

第一个取值永远都是nex

最后一个yield永远也得不到send传的值

列表推导式:一行代码几乎搞定你需要的任何列表

循环模式

l =[i for i in range(1,20) ]
print(l)

筛选模式

l3 = [i for i in range(1,15) if i % 3 == 0]
print(l3)

列表推导式优点:一行解决,方便

缺点:不易排错,不能超过三次循环

列表推导式不能解决所有列表的问题,所以不要太刻意用

生成器表达式:只需要将列表推导式[]  换成()

g = (i for i  in range(50))
print(g.__next__())   #0
print(g.__next__())   #1
print(g.__next__())   #2

一个next 打印一个

原文地址:https://www.cnblogs.com/beriuta/p/9534070.html