12 生成器

生成器


1.迭代器不能等价代换
def func():
yield "1"
yield "2"
g=func()
g.__next__() #用这种方式,一个个取值
func().__next__() #不用这种方式,因为这种方式,每次都是新创建一个迭代器,取出来的都是第一个值

生成器
1. 本质就是迭代器
两种方式写生成器
1. 生成器函数
2. 生成器表达式

2.生成器函数
函数内部有yield. yield返回 -> return
yield可以把函数分段执行
生成器函数被调用的时候. 返回生成器
def func():
yield
g = func() - 得到生成器
生成器的用法和迭代器基本一致
__next__() 开始执行生成器 . 执行到yield. 直到没有yield. 抛出StopIteration
send() 可以给上一个yield传值,send()不可以在第一个位置和最后一个位置出现
特点:
1. 省内存
2. 惰性机制, 不访问__next__() 就没有值.
3. 只能向前. 不能反复.

3.各种推导式(简单)
列表推导式 [结果 for循环 if判断]
字典推导式 {key: value for循环 if判断}
集合推导式 {key for循环 if判断}

4.生成器表达式(最难)
(结果 for循环 if判断)
惰性机制, 不访问__next__() 就没有值.
只能向前. 不能反复.
没有进行取值的时候就不执行代码
#打印
"""
    *
   ***
  *****
 *******
*********
"""
#思路:行   1  2  3  4  5  n
 #    *    1  3  5  7  9  2*n-1
 #   空白  4  3  2  1  0
# n=int(input("请输入行数:"))
# for i in range(1,n+1):
#     print((n-i)*" "+"*"*(2*i-1))


#方案二
n = int(input("请输入你要打印多少行"))
for i in range(1, n+1):
    # 方案一
    for k in range(n-i):
        print(" ", end="")
    for j in range(2 * i - 1):
        print("*", end="")
    print() # 换行

#求1-100内所有的质数的和
#思路:先判断某个数是否为质数,写成函数方便调用
def func(n):
    if n==1:
        return False
    elif n>=2:
        for i in range(2,n):#此处其实2的值没有取到,2直接走了else,返回是质数
            if n % i==0:
                return False
        else:
            return True
sum=0
for i in range(1,101):
    if func(i):
        sum+=i
print(sum)

  

#yield from lst
def func():
    lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
    lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
    yield from lst
    # yield lst[0]
    # yield lst[1]
    # yield lst[2]
    # yield lst[3]
    yield from lst2
g=func()#通过生成器函数获取生成器
for i in g:
    print(i)

#用生成器 每次取50件衣服
def func():
    lst=[]
    for i in range(1,1000):
        lst.append("衣服%s"%i)
        if i%50==0: #每次取50件衣服
            yield lst
            lst=[] #取完衣服下次,取之前用新的空的lst装
g=func()
print(g.__next__())#取第一批50件衣服
print(g.__next__())#取第2批50件衣服
View Code
原文地址:https://www.cnblogs.com/knighterrant/p/9890752.html