• 迭代器和生成器


    一、迭代器

    1、什么是迭代器

    迭代器是一个重复取值的工具,且每一次的取值都是基于上一代的结果,相当于一个更新换代的过程。

    2、迭代器的作用

    迭代器提供了一种不依赖索引取值的方法。

    3、可迭代对象

    内置有方法的都叫做可迭代对象

    4、迭代器对象

    内置有和方法的都叫做迭代器对象

    可以用dir()查看内置方法

    5、迭代器的使用

    字符串和容器数据类型的数据都是可迭代对象,当可迭代对象调用方法时可以编程一个迭代器,取值时调用方法即可一个一个取值,当值取完后若继续取值,将会报错,取值的过程时要一个取一个。

    PS:迭代器对象无论执行多少次iter方法得到的还是迭代器对象本身。

    l = [1,2,3,4]
    
    # 生成一个迭代器对象
    iter_l = l.__iter__()
    
    # 迭代器取值 调用__next__
    print(iter_l.__next__())  # 1
    print(iter_l.__next__())  # 2
    print(iter_l.__next__())  # 3
    print(iter_l.__next__())  # 4
    print(iter_l.__next__())  # 如果取完了 直接报错

    二、for循环的本质

    1、for循环的本质

    for循环内部执行的步骤:1.将in后面的对象调用转换成迭代器对象

    2.调用方法取值

    3.内部有异常

    2、迭代取值的特点

    从for循环的本质可以看出,迭代取值可以不依赖于素引取值,内存中永远只有for循环取得一条数据,不会导致内存溢出,但同时也有不能够获取指定值的元素、取完后会报StopIteration的错误。

    三、生成器

    1、什么是生成器

    本质是迭代器,是用户自定义的迭代器

    2、生成器的形式

    生成器在不调用的时候是函数,内部的返回值用yield返回。

    3、生成器的使用

    自定义的生成器在不调用的时候是函数,调用后是生成器,生成器的值的获取需要通过调用内部的方法,每调用一次通过yield返回一个值,此时迭代器的函数没用停止运行,而是暂停在yield处,等待下一次的方法获取返回值。若没有调用则停止运行。

    def func():
        print('first')
        yield  666  # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
        print('second')
        yield  777
        print('third')
        yield  888
        print('forth')
        yield
        yield
        
    # # yield后面跟的值就是调用迭代器__next__方法你能得到的值
    # # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
    g = func()  # 生成器初始化:将函数变成迭代器
    
    # 当只调用一次时,func函数先打印执行,先打印“first”,获取到迭代器g的一个值,停止运行
    print(g.__next__())  # 'first'  666
    
    # 当调用两次的时候,第一次去之后停在yield,继续运行,进行第二次的值的获取
    print(g.__next__())  # 'second'  777

    yield可以通过调用send()方法接收外部的值,通过调用send()方法,给yield左边的变量传值,然后执行方法。

    def dog(name):
        print('%s 准备开吃'%name)
        while True:
            food = yield
            print('%s 吃了 %s'%(name,food))
    
            
    g = dog('egon')
    print(g.__next__()) # 必须先将代码运行至yield 才能够为其传值
    print(g.send('狗不理包子'))  # 给yield左边的变量传参  触发了__next__方法
    
    # egon 准备开吃
    # egon 吃了 狗不理包子

    4、自定义简单版range方法

    def range1(start, end, s = 1):
        """
        :param start:起始值 
        :param end: 结束zhi
        :param s: 取值间隔s-1
        :return: 从起始值开始,每间隔s-1个数取值
        """
        while start < end:
            yield start
            start = start + s
    
    
    a = range1(1,10,2)
    print(a.__next__())  # 1
    print(a.__next__())  # 3
    print(a.__next__())  # 5
    print(a.__next__())  # 7
    print(a.__next__())  # 9

    四、常用内置方法

    print(abs(-11.11))  # 求绝对值
    l = [0,1,0]
    print(all(l))  # 只要有一个为False就返回False
    print(any(l))  # 只要有一个位True就返回True
    
    
    def index():
        username = '我是局部名称空间里面的username'
        print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
        print(globals())  # 无论在哪 查看的都是全局名称空间
    index()
    
    
    print(bin(10))
    print(oct(10))
    print(hex(10))
    print(int('0b1010',2))
    
    
    print(bool(1))
    print(bool(0))
    
    
    s = 'hello'
    print(s.encode('utf-8'))
    print(bytes(s,encoding='utf-8'))
    
    
    # 可调用的(可以加括号执行相应功能的)
    l = [1,2,3]
    def index():
        pass
    print(callable(l))
    print(callable(index))
    
    
    print(chr(97))  # 将数字转换成ascii码表对应的字符
    print(ord('a'))  # 将字符按照ascii表转成对应的数字
    
    
    """
    面向对象需要学习的方法
    classmethod
    delattr
    getattr
    hasattr
    issubclass
    property
    repr
    setattr
    super
    staticmethod
    """
    
    
    # dir获取当前对象名称空间里面的名字
    l = [1,2,3]
    print(dir(l))
    #
    # import test
    # print(dir(test))
    # print(test.name)
    
    
    # divmod  分页器
    print(divmod(101,10))
    total_num,more = divmod(900,11)
    if more:
        total_num += 1
    print('总页数:',total_num)
    
    
    # enumerate 枚举
    l = ['a','b']
    for i,j in enumerate(l,1):
        print(i,j)
    
    
    # eval  exec
    s = """
    print('hello baby~')
    x = 1
    y = 2
    print(x + y)
    
    """
    eval(s)
    exec(s)
    
    # eval不支持逻辑代码,只支持一些简单的python代码
    s1 = """
    print(1 + 2)
    for i in range(10):
        print(i)
    """
    eval(s1)
    exec(s1)
    
    name = 'jason'
    s2 = """
    name
    """
    print(eval(s2))
    
    
    # format 三种玩法
    # {}占位
    # {index} 索引
    # {name} 指名道姓
    
    # print(globals())
    
    
    def login():
        """
        一起嗨皮
        :return:
        """
    print(help(login))
    
    
    # isinstance 后面统一改方法判断对象是否属于某个数据类型
    n = 1
    print(type(n))
    print(isinstance(n,list))  # 判断对象是否属于某个数据类型
    
    
    print(pow(2,3))
    
    
    print(round(3.4))
    常用内置函数

    五、面向过程的编程

    面向过程编程的思想:类似于设计一条流水线,按照特定的顺序执行程序。可以将复杂的问题流程化,从而变得简单化,但是可扩展性比较差,一旦某一步骤需要修改时,全局都会受到影响。

    比如设计一个用户注册功能,可以分三步,分别依次为获取用户输入、处理用户输入信息、存储用户信息。

    def get_info():
        while True:
            username = input(">>>:").strip()
            if not username.isalpha():  # 判断字符串不能包含数字
                print('不能包含数字')
                continue
            password = input('>>>:').strip()
            confirm_password = input("confirm>>>:").strip()
            if password == confirm_password:
                d = {
                    '1':'user',
                    '2':'admin'
                }
                while True:
                    print("""
                        1 普通用户
                        2 管理员
                    """)
                    choice = input('please choice user type to register>>>:').strip()
                    if choice not in d:continue
                    user_type = d.get(choice)
                    operate_data(username,password,user_type)
                    break
            else:
                print('两次密码不一致')
    
    # 2.处理用户信息
    def operate_data(username,password,user_type):
        # jason|123
        res = '%s|%s|%s
    '%(username,password,user_type)
        save_data(res,'userinfo.txt')
    
    # 3.存储到文件中
    def save_data(res,file_name):
        with open(file_name,'a',encoding='utf-8') as f:
            f.write(res)
    
    def register():
        get_info()
    
    register()

    一旦需要获取用户的资产等其它信息时,该注册程序的三个步骤全部都要修改。这就是所谓的流程简单化,扩展性较差。

  • 相关阅读:
    pip不是内部或外部命令也不是可运行的程序或批处理文件的问题
    动态规划 leetcode 343,279,91 & 639. Decode Ways,62,63,198
    动态规划 70.climbing Stairs ,120,64
    (双指针+链表) leetcode 19. Remove Nth Node from End of List,61. Rotate List,143. Reorder List,234. Palindrome Linked List
    建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237
    链表 206 Reverse Linked List, 92,86, 328, 2, 445
    (数组,哈希表) 219.Contains Duplicate(2),217 Contain Duplicate, 220(3)
    重装系统
    java常用IO
    端口
  • 原文地址:https://www.cnblogs.com/le-le666/p/11190847.html
Copyright © 2020-2023  润新知