生成器以及面试题

1.生成器
背景:列表太占内存,所以我们想要多少取多少
本质是迭代器 写法和迭代器不一样 用法一样

  return和yield都可以返回数据
  特点:
  1.节省内存 几乎不占用内存
  2.惰性机制
  3.只能往前走
  # 找不到yield报错
  # 对程序效率提升特别大

  #send()也可以实现类似__next__()效果
  给上一个yield传值
  获取下一条值得效果基本一致
  接收当前yield的值 同时把给上一条yield赋值
  #send不可以在开头
  #最后一个


  send和next的区别:
    send不可以在开头
    #send不可以在开头
    send可以给上一个yield传值,不能给最后一个yield传值
  #生成器可以直接使用for循环
  #生成器也可以转化为列表

2.生成器函数
  g = func() # 啥都没做
    1.send #第一次不用send
    2.函数中的最后一个yield不能接受新的值
    3.预激生成器的装饰器例子
3.各种推导式 ===>列表/字典/集合/“元组”(生成器)
  元组没有推导式
  生成器表达式:(结果 for if)
  可以直接使用生成器表达式直接创建生成器:gen = (i for i in range(10))

  生成器表达式/列表推导式
  列表推导式:一次性把所有的数据创建出来,容易产生内存浪费
  生成器表达式:记录一下代码。每次需要的时候去生成器里面执行一次代码
  特性:
    1.节省内存
    2.惰性机制
    3.只能向前


4.python3里面的新语法yield from

下面这两个函数的骚操作是一样的:

 1 def func():
 2     s1 = 'test'
 3     for i in s1:
 4         yield i
 5 
 6 
 7 g = func()
 8 for i in g:
 9     print(i, end=" ")
10 
11 
12 def func1():
13     s1 = 'test'
14     yield from s1
15 
16 
17 g = func1()
18 for i in g:
19     print(i, end=" ")
20 """
21 t e s t t e s t 
22 """
View Code

5.生成器表达式(笔试题)

  1.带装饰器的生成器获取平均值(有点像C语言里面的链表)   ====>这个代码实在是太经典了 多撸几遍

 1 def init(f):
 2     def inner(*args, **kwargs):
 3         g = f(*args, **kwargs)
 4         g.__next__()
 5         return g
 6 
 7     return inner
 8 
 9 
10 @init  # average = init(average)
11 def average():
12     sum1 = 0
13     count = 0
14     avg = 0
15     while True:
16         num = yield avg
17         count += 1
18         sum1 += num
19         avg = sum1 / count
20 
21 
22 g = average()
23 # g.__next__()  # 可以加一个装饰器把这句话纳入收起来
24 print(g.send(10))
25 print(g.send(110))
26 """
27 10.0
28 60.0
29 """
View Code

  2.生成器函数和生成器表达式混合(此题难度系数:让无数英雄竞折腰)

 1 # 面试题
 2 def demo():
 3     for i in range(4):
 4         yield i
 5 
 6 
 7 g = demo()
 8 g1 = (i for i in g)
 9 g2 = (i for i in g1)
10 # g2 = (i for i in (i for i in demo())) # 等价于这个
11 print(list(g1))
12 print(list(g2))
13 """
14 [0, 1, 2, 3]
15 []
16 """
View Code
 1 def add(n, i):
 2     return n + i
 3 
 4 
 5 def test():
 6     for i in range(0, 10, 2):
 7         yield i
 8 
 9 
10 g = test()
11 for n in [1, 10, 4, 20]:
12     g = (add(n, i) for i in g)
13 """
14 上面的骚操作拆开来看,实际上就等于下面这几步
15 n = 2
16 g = (add(n, i) for i in test())
17 
18 n = 10
19 g = (add(n, i) for i in (add(n, i) for i in test()))
20 因为惰性机制 直到打印的时候才去取值
21 所以实际上 嵌套的列表里面的最后一个值 起作用
22 并且有几个值就起了几次作用
23 """
24 print(list(g))
View Code
原文地址:https://www.cnblogs.com/d9e84208/p/10587438.html