首页 > 其他分享 >生成器总结

生成器总结

时间:2023-03-10 10:34:48浏览次数:44  
标签:总结 __ 生成器 yield start num print

生成器

1、生成器对象的本质

生成器对象其实本质上就是迭代器对象,内置有双下__ iter__ 和 __next __方法

2、区别

迭代器对象就是Python解释器提供的各种数据类型或是文件对象,但是生成器对象是程序员编写的代码或者函数之类的关键字。

3、生成器的两种形式

1.使用def定义函数然后内部使用yield关键字

在使用函数+yield关键字定义生成器的时候需要注意当我们使用括号调用函数的时候并没有运行这个函数,而是把这个函数体代码变成了一个生成器对象,之后我们想要调用函数产生数据就需要跟迭代器一样使用 __ next __方法,并且每次运行的时候如果遇到yield关键字就会停止到那个位置,如果下方代码还有yield关键字,下一次运行双下划线的next方法就会运行到下一个yield关键字处停止。

def my_iter():
    print('哈哈哈 椰子汁很好喝')
    yield
'''
1.函数体代码中如果有yield关键字
那么函数名加括号并不会执行函数体代码
会生成一个生成器对象(迭代器对象)
'''
res = my_iter()
print(res)
'''2.使用加括号之后的结果调用__next__才会执行函数体代码'''
res.__next__()

# <generator object my_iter at 0x000002161040A900>
# 哈哈哈 椰子汁很好喝

下面是多个yield的使用场景:

'''3.每次执行完__ next __ 代码都会停在yield位置 下次基于该位置继续往下找第二个yield'''
def my_iter():
    print('哈哈哈 椰子汁很好喝')
    yield 111, 222, 333.
    print('呵呵呵 从小喝到大')
    yield 111, 222, 333
    print('嘿嘿嘿 特种兵牌还可以')
    yield 111, 222, 333
    print('哼哼哼 千万别整多了 倒沫子 头发掉光光')
    yield 111, 222, 333

:在上面的代码运行过程中我们也发现了yield关键字跟return一样可以返回返回值

2.使用生成器表达式

可以简化代码,节省内存

l1 = (i ** 2 for i in rang(100))  # 生成器对象
print(l1)
for i in l1:
    print(i)

使用生成器生成对象后需要使用循环输出里面的数据值,或者转换类型后一次性输出

3、自定义生成器对标range功能(一个参数 两个参数 三个参数 迭代器对象)

考虑到range功能复杂,所以我们这里要使用函数加yield关键字的方法来简历自定义生成器

def my_range(start_num, end_num=None, step=1):
    # 判断end_num是否有值 没有值说明用户只给了一个值 起始数字应该是0 终止位置应该是传的值
    is_back = False
    if not end_num:
        # 判断第二个结束为止是否有参数,如果没有就把传给起始位置的参数给结束为止,其实位置变成0
        end_num = start_num
        start_num = 0
    if step == 0:
        yield '位移量不能为0'
    if step < 0:
        # 判断取值的步频是否为反方向
        # 如果是反方向的步频,判断起始位置和结束为止是否前面的大后面的小
        if not start_num > end_num:
            yield '参数大小错误'
        else:
            is_back = True
            # 起始位置和结束为止是前面的大后面的小的时候就返回True
    while start_num < end_num or is_back:
        # 起始位置小于结束位置的时候或是步频为负数的时候判断正确的话就输出数据值
        if start_num < end_num:
            # 起始位置小于结束位置
            print(start_num)
            yield start_num
            start_num += step
        elif is_back:
            # 步频为负数
            if start_num > end_num:
                yield start_num
                start_num += step
            else:
                is_back = False


# 定义了模仿range方法的功能后,用for循环的方式调用内部数据值

for i in my_range(100, 50, 0):
    print(i)

二、yield冷门用法

当我们使用yield关键字的时候可以用变量名绑定yield关键字,然后就可以使用send方法传参,然后会再次运行到yield关键字处停止运行


def eat(name, food=None):
    print(f'{name}准备用餐')
    while True:
        food = yield
        print(f'{name}正在吃{food}')


res = eat('jason')
res.__next__()
res.send('汉堡')  # 1.将括号内的数据传给yield前面的变量名 2.再自动调用__next__
res.send('包子')
res.send('面条')
'''
jason准备用餐
jason正在吃汉堡
jason正在吃包子
jason正在吃面条
'''

标签:总结,__,生成器,yield,start,num,print
From: https://www.cnblogs.com/wei0919/p/17202518.html

相关文章

  • 一句话shell总结及开启3389端口
    ASP一句话:<%execute(request("aaa"))%><%eval(eval(chr(114)+chr(101)+chr(113)+chr(117)+chr(101)+chr(115)+chr(116))("a"))%><%evalrequest("aaa")%>PHP一句话:......
  • 总结一下搭建个人网站《曼云古籍在线识别》的完整流程
    继2年前开发出一个标注工具PaddleOCRLabel之后,我就开始炼丹之旅,全面allin人工智能,历时一年,终于炼成了第一颗“丹”——针对于古籍的ocr识别模型。经过400万图片的验证,目前......
  • 总结20230309
    今天上了体育课。今天进行了卫生大联查,期待了许久的领导,也没能如愿的来六楼。下午上了羽毛球课,练习了反手发球、双打步法、反手打球,课后又和朋友们打了接近一小时的双打,......
  • 3.9学习总结
    公有私有publicclassClassName{//...}privatebooleanmyFlag;staticfinaldoubleweeks=9.5;protectedstaticfinalintBOXWIDTH=42;publicstaticvoi......
  • 3.11学习总结
    今天学习了RecyclerViewbuild.gradle文件下//添加RecyclerView的依赖包implementation'androidx.recyclerview:recyclerview-selection:1.1.0'MainActivity.javapacka......
  • 3月9日每日总结
    今天上午有课,下午从5点半开始自习,到9点半结束,因为英语四级考试在即,一共四个小时花在英语上三个小时,最后一个小时学习了MySQL增删改查的语法,语句命令,之前总是套用别人的魔板......
  • 3.10学习总结
    今天学习了ListViewmain.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_wi......
  • Python迭代与生成器
    1、迭代_iter_对象方法可迭代对象,返回迭代器__next_对象方法迭代器对象,返回迭代中每一步的运算iter(object)内置函数得到object的迭代器next(object)......
  • 每日总结-23.3.9
    今天学习了获取系统时间并且使用DatePicker标签自由选择时间<DatePickerandroid:layout_margin="10dp"android:id="@+id/select_time"an......
  • 3.9总结
    今日使用idea对安卓进行了初步学习,代码如下packagetex;importjava.util.Scanner;publicclasstext{publicstaticintmaxSubArrayMethodTwo(intarr[]){i......