关于生成器---(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