python3 生成器和生成器表达式

 

'''普通函数'''
def func():
    print(111)
    return 222

ret = func()  # 111
print(ret)  # 222
111
222

'''函数中含有yield就是生成器'''
def func():
    print(111)
    yield 222
    
gen = func()
print(gen)  # <generator object func at 0x0000000006085D00>
ret1 = gen.__next__()  # 111
print(ret1)  # 222
<generator object func at 0x0000000007A8BB48>
111
222

def func():
    print(111)
    yield 22
    print(333)
    yield 444
    
gen = func()  
ret = gen.__next__()  # 111
print(ret)  # 22
ret2 = gen.__next__()  # 333
print(ret2)  # 444
ret3 = gen.__next__()  # StopIteration:  # 值取空,就报StopIteration
print(ret3)
111
22
333
444
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-25-9050db3134ee> in <module>()
     10 ret2 = gen.__next__()
     11 print(ret2)
---> 12 ret3 = gen.__next__()
     13 print(ret3)

StopIteration: 

'''send和__next__()区别
    1.send和next()都是让生成器向下走一次
    2.send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能使用send()
'''
def func():
    print(111)
    a = yield "aaa"
    print("a = ", a)
    b = yield "bbb"
    print("b = ", b)
    c = yield "ccc"
    print("c = ", c)
    yield "Bye"
    
gen = func()
print(gen.__next__()) # 111 aaa
print(gen.__next__()) # a = None bbb
print(gen.__next__()) # b = None ccc
print(gen.__next__())  # c = None  Bye
print(gen.__next__()) # StopIteration
111
aaa
a =  None
bbb
b =  None
ccc
c =  None
Bye
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-26-e1ddf9d0af94> in <module>()
     14 print(gen.__next__()) # b = bbb ccc
     15 print(gen.__next__())  # c = ccc  Bye
---> 16 print(gen.__next__()) # StopIteration

StopIteration: 

def func():
    print(111)
    a = yield "aaa"
    print("a = ", a)
    b = yield "bbb"
    print("b = ", b)
    c = yield "ccc"
    print("c = ", c)
    yield "Bye"
    
gen = func()
print(gen.__next__())  # 111 aaa
ret1 = gen.send("apple")  # a = apple 
print(ret1)  # bbb
ret2 = gen.send("banana")  # b = banana
print(ret2)  # ccc
ret3 = gen.send("orange")  # c = orange
print(ret3)  # Bye
ret4 = gen.send("pear")  # StopIteration
111
aaa
a =  apple
bbb
b =  banana
ccc
c =  orange
Bye
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-27-3a8a2fe89824> in <module>()
     17 ret3 = gen.send("orange")  # c = orange
     18 print(ret3)  # Bye
---> 19 ret4 = gen.send("pear")  # StopIteration

StopIteration: 

'''生成器可以使用for循环去内部的元素'''
def func():
    print(111)
    yield 222
    print(333)
    yield 444
    print(555)
    yield 666
    
gen = func()
for i in gen:
    print(i)
111
222
333
444
555
666
'''yield在循环体内'''
def func(n):
    print("start...")
    count = 0
    while count < n:
        count += 1
        yield count
    print("end...")

g = func(5)

for i in g:  #for循环本质就是next下一个元素
    print(i)

返回结果:
start...
1
2
3
4
5
end...

 

'''注意区分send()给上一个yield位置传递一个值,yield是向外返回一个值'''
def func():
    print("apple")
    y1 = yield 2
    print(y1, " = banana")
    y2 = yield 1
    print(y2, " = orange")
    y3 = yield 3
    print(y3)

g = func()
print(g.__next__())
print(next(g))
print(g.send("big"))

返回结果:
apple
2
None  = banana
1
big  = orange
3

 

'''生成器表达式(结果 for循环 if语句)'''
# lst = [i*i for i in range(5)]
# print(lst) #列表生成式,直接生成一个列表,下面把中括号换为小括号,就是一个生成器
# g = (i*i for i in range(5))
# print(g) #生成器对象,省内存
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g)) #StopIteration

 

'''yield from是将列表中的每一个元素返回'''
def gen():
    lst = ["apple", "banana", "pear", "orange"]
    yield from lst
    
g = gen()
for i in g:
    print(i)
apple
banana
pear
orange
def gen():
    lst = ["apple", "banana", "orange", "pear"]
    lst2 = ["peach", "watermelon", "strawberry", "blueberry"]
    yield from lst
    yield from lst2
    
g = gen()
print(list(g))  # ['apple', 'banana', 'orange', 'pear', 'peach', 'watermelon', 'strawberry', 'blueberry']
['apple', 'banana', 'orange', 'pear', 'peach', 'watermelon', 'strawberry', 'blueberry']
'''
一个面试题,难度系数50000000000颗星
'''
# def add(a, b):
#     return a + b
#
# def test():
#     for r_i in range(4):
#         yield r_i
#
# g = test() #g是一个生成器,也是一个迭代器
#
# for n in [2, 10]:
#     g = (add(n, i) for i in g)
#
# print(list(g))
'''
分析,当n=2时, g = (add(n, i) for i in g) 右边是一个生成器表达式, g就是一个生成器
当n=10时, g = (add(n, i) for i in (add(n, i) for i in g)) 右边是一个生成器表达式, g就是一个生成器
当程序执行到list(g)时,开始取生成器里的值
当n=10时,g = (add(10, i) for i in (add(10, i) for i in g))
g = (add(10, i) for i in (10, 11, 12, 13))
g = (20, 21, 22, 23)
所以打印出来的值就是[20, 21, 22, 23]
'''

 

 

posted on 2019-04-24 15:07  lilyxiaoyy  阅读(617)  评论(0编辑  收藏  举报

返回
顶部