zoukankan      html  css  js  c++  java
  • 关于生成器---(yield)

    生成器:是自定义的迭代器(自己用python代码写的迭代器),函数中见到yield的就是生成器

    那么yield前后的变量又该怎么理解

    看例子一

    def counter(name):
        print('%s ready to count'%name)
        num_list=[]
        while True: #这个语句的作用是循环利用yield,这样的话对象就可以无限传值了
            #yield前的变量是接收值的
            num=yield '现在的列表是%s'%num_list #yield后面的变量会打印处理
            num_list.append(num)
            print('%s start to count %s'%(name,num))
    
    e=counter('xincheng')
    print(e.send(None)) #或者 next(e)
    print(e.send('1'))
    print(e.send('2'))
    for i in range(3,10):
        print(e.send(i))

    例子一打印结果为:

    xincheng ready to count
    现在的列表是[]
    xincheng start to count 1
    现在的列表是['1']
    xincheng start to count 2
    现在的列表是['1', '2']
    xincheng start to count 3
    现在的列表是['1', '2', 3]
    xincheng start to count 4
    现在的列表是['1', '2', 3, 4]
    xincheng start to count 5
    现在的列表是['1', '2', 3, 4, 5]
    xincheng start to count 6
    现在的列表是['1', '2', 3, 4, 5, 6]
    xincheng start to count 7
    现在的列表是['1', '2', 3, 4, 5, 6, 7]
    xincheng start to count 8
    现在的列表是['1', '2', 3, 4, 5, 6, 7, 8]
    xincheng start to count 9
    现在的列表是['1', '2', 3, 4, 5, 6, 7, 8, 9]
    例子一结果

     例子二:

    def counter(name):
        print('%s ready to count'%name)
        num_list=[]
        while True:
            num=yield num_list,'hehe' #yield后面的变量会答应处理,多个用,隔开,结果就会放入一个元组中
            num_list.append(num)
            print('%s start to count %s'%(name,num)) #yield后面的语句一般为下一个yield的开始
    
    e=counter('xincheng')
    next(e)
    s=e.send('1') #xincheng start to count 1
    print(s,type(s)) #(['1'], 'hehe') <class 'tuple'> yield后面的东西是给对象传的值,多个值放在一个元组中

     例子三:yield from 可以从一些地方获取值

    def gen1():
        for c in 'ab':
            yield c
        for i in range(3):
            yield i
    print(list(gen1()))
    
    def gen2():
        yield from 'ab'
        yield from range(3)
    
    print(list(gen2()))
    
    #两个print的值都为['a', 'b', 0, 1, 2]

     面试题一

    def demo():
        for i in range(4):
            yield i
    g=demo()
    g1=(i for i in g)
    g2=(i for i in g1)
    
    print(list(g1))  #[0, 1, 2, 3]
    print(list(g2))  #[]

    #g是第一个生成器,g1取得值来自于g,g2取值来自于g1,归根到底还是g,list是可迭代对象,将g1赋予list得方法,其实是从g中取值,而且取完了,g2自然就是空值了

    请看下面得变体
    def demo():
    for i in range(4):
    yield i

    g=demo()
    g1=(i for i in g)
    g2=(i for i in g1)
    print(next(g)) # 0
    print(next(g1)) # 1
    print(next(g2)) # 2

     面试题二:

    def add(n,i):
        return n+i
    
    def test():
        for i in range(4):
            yield i
    
    g=test()
    for n in [1,10]:
        g=(add(n,i) for i in g)
    
    print(list(g))
    
    #此例子的for循环中有两个元素,其结果为 [20, 21, 22, 23]
    
    #如果将for循环下面得表达式换成g=[add(n,i) for i in g] 换成了【】,结果为[11, 12, 13, 14]
    
    #如果将for循环的表达式换成 for n in [1,3,10]  或者 for n in [1,11,10] 都是三个元素,其结果为[30, 31, 32, 33]
    
    #如果是 for n in [1,3,6,7,10,11,100,10]总共8个元素 其结果为[80, 81, 82, 83]

     面试二总结:生成器的特点是惰性机制,也就是说你找它要,它才会给你值

      在上一题的for循环中,不管你循环多少次,生成器的取值都是列表【】中的最后一个值

      g在取值前,是一个内存地址,for循环一直改变着g的内存地址,最后是n=10的内存地址

      for循环一次,g中的值就加一次,每次加的都是n=10的内存地址的值 

      for循环第一次: 10+0  10+1 10+2 10+3

      for循环第二次:10+10+0  10+10+1 10+10+2 10+10+3

      如果有第三次:10*3+0 10*3+1  10*3+2 10*3+3

      。。。。。。

  • 相关阅读:
    团队冲刺八
    第十一周学习进度
    团队冲刺七
    团队冲刺六
    团队冲刺五
    冲刺第五天
    冲刺第四天
    冲刺第三天
    冲刺第二天
    冲刺第一天
  • 原文地址:https://www.cnblogs.com/mmyy-blog/p/9298076.html
Copyright © 2011-2022 走看看