python中yield的用法详解——最简单,最清晰的解释

在这里插入图片描述


前言

提示:这里可以添加本文要记录的大概内容:


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是迭代器与生成器?

1.可迭代对象

实现了__iter__方法,并且该方法返回一个迭代器 这样子的对象就是一个可迭代对象

2.可迭代对象有哪些?

容器类型都是可迭代对象 # range # 打开的文件,socket # 凡是有__iter__并且这个方法返回一个迭代器的对象都称之为可迭代对象

3.迭代器

(1)任何实现了__iter__()和__next__()都是迭代器
(2) iter() 返回自身 # next() 返回下一个值
(3) 如果容器中没有更过元素了,则抛出StopIteration
(4) 在for循环中,如果遇到了StopIteration时,就退出循环
(5) 迭代器一定是一个可迭代对象,迭代器是一个懒加载模式,用的时候才生成.
特殊的迭代器, 就是为了写迭代器更加的优雅

二、什么是列表推导式?

1.列表推导式;

mystr = “abcd”
=> [“a”,“b”,“c”,“d”]

代码如下(示例):


mystr = "abcdABCDmd/"
mylist = [item for item in mystr if item.islower()]
print(mylist, type(mylist))


mystr = "abcdABCDmd/"
mylist0 = []
for item in mystr:
    if item.islower():
        mylist0.append(item)
print(mylist0, type(mylist0))

2.yield关键 -->生成器函数

yield关键字:保留中间算法,下次继续执行
当调用next值时,遇到yield就是暂停运行,并且返回yield后面的值
当再次调用next时,会从刚才暂停的地方继续运行,直到运行下一个yield

def get_content():
    print("start yield....")
    yield 3
    print("second yield...")
    yield 4
    print("third yield...")
    yield 5
    print("end.....")
#
a = get_content()
# print(dir(a))
print("*"*20)
print(next(a))
print(next(a))
print("*"*20)
result = next(a)
print(result)
print(next(a))

def get_func():
    i = 0
    while True:
        i +=1
        yield i
a = get_func()
print(next(a))
print(next(a))



使用生成器实现斐波拉契数列

使用生成器实现斐波拉契数列
1123581321

########send
def counter():
   count = 1
   while True:
       val = yield count
       print(f'val is {val}')
       if val is not None:
           print(f'val is {val}')
           count = val
       else:
           count +=1
#
count = counter()
print(next(count))
# print(next(count))
count.send(10)  #返回一个新的值给yield count
print(next(count))

**

手动关闭当前生成器,关闭之后不能再继续生成值*

 count.close()
 print(next(count))


 yield  与field from
 def f1():
     yield range(10)
#
 def f2():
     yield from range(10)
     #for item in range(10):
     #   yield item
 it1 = f1()
 it2 = f2()
 print(it1)
 print(it2)
 for i in it1:
     print(i)
 print("*"*20)
 for i in it2:
     print(i)

3.小案例:

代码如下(示例):


# 编写高质量代码 => 减少循环次数
# 打印30以内的数字,所有能被3整除的整数
print([x for x in range(30) if x % 3 == 0])
print([x for x in range(0,30,3)])
print(list(range(0,30,3)))


print([x*x for x in range(30) if x % 3 == 0])
print([x**2 for x in range(0,30,3)])

找到名字中包含2个e的名字放到列表

names = [
    ['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
    ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva', 'Elven']
]

# 找到名字中包含2个e的名字放到列表
print([item for list0 in names for item in list0 if item.lower().count('e') == 2])

mynames = []
for list0 in names:
    for item in list0:
        if item.lower().count('e') == 2:
            mynames.append(item)

过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母

# 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
q1 =  ['a','ab','abc','abcd','abcde']
print([item.upper() for item in q1 if len(item) >= 3])


print([item.lower() if 'E' not in item  else item.upper()
       for list0 in names for item in list0
       if item.lower().count('e') == 2])

求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表

li = [-1, 2, 1, 9]
print({i**2 for i in li})

# 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
# [(0,1),(0,3),(0,5), (2,1), (2,3)....]
# 列表推导式 , for , for
print([(x,y) for x in range(6) if x%2==0 for y in range(6) if y%2])
# 第二种更高效
print([(x,y) for x in range(0,6,2) for y in range(1,6,2)])


快速更换key和value,第二种写法更高效


# 快速更换key和value
# q3 = {'a': 10, 'b': 34} => q3 = {10:'a', 34:'b'}
q={'a':10,'b':34}
my_di = {q[key]:key for key in q}
print(my_di)
# 推荐 => 清晰
my_di = {value:key for key,value in q.items()}
print(my_di)

# 合并大小写对应的value值,将k统一成小写
# {'a':5, 'b':9, 'c':3}
q4 = {'B':3, 'a':1, 'b':6, 'c':3, 'A':4}
print({key.lower():q4.get(key.lower(),0)+q4.get(key.upper(),0) for key in q4})
# 如何减少运算次数


总结

1.迭代器与生成器内容很重要,一定要理解之间的关系.尤其是yield关键字:保留中间算法,下次继续执行

2.对于后面的小案例一定要动手去敲一敲,有任何问题可以留言和评论.

3.如果你看到这里了,麻烦👍 + 关注哈,感谢支持,码字不易,谢谢理解.
第二篇在码字中…敬请期待…

在这里插入图片描述

  • 21
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未末0902

你的鼓励与支持是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值