函数进阶3 —— 生成器、yield from

今天我们在进一步了解一下,生成器。

①:

1 def func():
2     print('这是函数func')
3     return '函数func'
4 func()

结果是 

这是函数func

②:

1 def func1():
2     print('这是函数func1')
3     yield '函数func'
4 func1()

③:

1 def func1():
2     print('这是函数func1')
3     yield '函数func'
4 print(func1())

结果: 

<generator object func1 at 0x0000000002138E58>  返回的是func1的内存地址。

有没有发现这三个的值不一样。

那么 return 和yield 的区别是什么呢?

return是返回值,直接停止这个函数,

yield是分段停止这个函数。

1.生成器的本质就是迭代器
2.通过函数变成一个生成器
 1 def func():
 2     print(1)
 3     yield 5  # 我的函数走到这了
 4     print(2)
 5     yield 9  # 我的函数走到这了
 6 
 7 g = func()  # 生成一个生成器
 8 
 9 print(g.__next__())
10 print(g.__next__())
 
def func():
    print(1)
    # return 5
    yield 5
print(func().__next__())  # 这样生成一个生成器
print(func().__next__())  # 这样生成一个生成器
print(func().__next__())  # 这样生成一个生成器
print(func().__next__())  # 这样生成一个生成器
 

  

 1 def func():
 2     print(1)
 3     yield 5  # 我的函数走到这了
 4     print(2)
 5     yield 9  # 我的函数走到这了
 6 
 7 g = func()  # 生成一个生成器
 8 print(g.__next__())
 9 print(g.__next__())
10 
11 碰到return就结束函数
12 碰到yield不结束就挂起
13 生成器的好处,非常节省内存
 
def func():
    print(1)
    a = yield 2  # 1.挂起 2.返回值 3.接受值
    print(a)   # '123'
    print(3)
    b = yield 4
    print(b)   #'234'
    c = yield 9
g = func()

print(g.__next__())   #1 2  g.send(None)
print(g.send('123'))  # send = next+传值
print(g.send('234'))  # send = next+传值
# 第一次调用生成器的时候使用send里边的值必须是None
 
1 def func():
2     yield 1
3     yield 2
4 
5 g = func()
6 ret = g.__next__()
7 print(ret+4)
8 print(g.__next__())

2.yield  from

 1 def func():
 2     li = [1,2,3,4]
 3     # yield li
 4     yield from li  #(= for yield in li)
 5 
 6 ret = func()  # 把生成器的地址给了ret
 7 print('is ret',ret.__next__())  #一个生成器
 8 print('is ret',ret.__next__())
 9 # 执行ret这个变量的指向的生成器地址:
10 print('is ret',ret)
11 # # 在全局空间找到一个变量叫做ret的,打印它的值 值就是生成器的地址
 1 def func():
 2     li = [1,2,3,4]
 3     l2 = [5,6,7,8]
 4     # yield from li
 5     # yield from l2
 6     for i in li:
 7         yield i
 8 
 9     for em in l2:
10         yield em
11 #
12 ret = func()  # 把生成器的地址给了ret
13 print('is ret',ret.__next__())
14 print('is ret',ret.__next__())
15 print('is ret',ret.__next__())
16 print('is ret',ret.__next__())
17 print('is ret',ret.__next__())
yield from li  =  for i in li
           yield i 

 1 # 总结:
 2 #     1.生成器的本质就是一个迭代器
 3 #     2.生成器一定是一个迭代器,迭代器不一定是一个生成器
 4 #     3.生成器是可以让程序员自己定义的一个迭代器
 5 #     4.生成器的好处,节省内存空间
 6 #     5.生成器的特性 一次性的,惰性机制,从上向下
 7 #     6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None)
 8 #         值必须是None,一般我建议你们使用__next__
 9 #     7.    python2 iter()  next()
10 #           python3 iter()  next()  __next__() __iter__()
11 #     8.yield from 将可迭代对象元素逐个返回
 

3.推导式

一个容器包在最外面,结果,语法:

[结果,语法] #容器

1 # 列表推导式
2 li = []
3 for i in range(10):
4     li.append(i)
5 print(li)
6 
7 print([i for i in range(10)])
 
1 li = []
2 for i in range(10):
3     if i%2 == 1:
4         li.append(i)
5 print(li)
6 
7 print([i for i in range(10) if i%2 == 0])  # 过滤(筛选)
 

for循环的嵌套:

1 li = []
2 for i in range(3):
3     for em in range(3):
4         li.append(em)
5 print(li)
6 
7 # print([j for i in range(10) for em in range(3) for j in range(5)])

其字典、集合的推导式同列表推导式,没有元组推导式。

 
1 g = (i for i in range(10))
2 print(g)
3 
4 结果:<generator object <genexpr> at 0x0000000002168E58>
 
 
 

猜你喜欢

转载自www.cnblogs.com/chitangyuanlai/p/10542045.html