zoukankan      html  css  js  c++  java
  • 迭代器和生成器

    一、什么是迭代器

    迭代指的是一个重复的过程,每一次重复都是基于上一次的结果而来的

    # 这里的循环也是一个迭代,每次基于上一次的结果而取值
    li = 'hello'
    
    i = 0
    while i < len(li):
        print(li[i])
        i += 1

    迭代器指的是迭代取值的工具,该工具的特点是可以不依赖于索引取值

    二、为何要用迭代器

      为了找出一种通用的、可以不依赖于索引的迭代取值方式

    三、如何使用迭代器

    可迭代的对象:但凡内置有 __iter__ 方法的对象都称之为可迭代的对象

      如:str、list、tuple、dict、set、文件对象

    迭代器对象:既内置有 __iter__方法,又内置有 __next__ 方法

      如:文件对象

    关于 __iter__ 方法:

      调用可迭代对象的 __iter__ 会的到一个迭代器对象

      调用迭代器对象的 __iter__ 会的到迭代器本身

    可迭代对象可以转化为迭代器对象:调用可迭代对象内置的 __iter__ 方法会有一个返回值,该返回值就是对应的迭代器对象

    dic = {'x':1, 'y':2, 'z':3}
    
    iter_dic = dic.__iter__()
    print(iter_dic)
    
    res1 = iter_dic.__next__()
    print(res1)
    
    res2 = iter_dic.__next__()
    print(res2)
    
    res3 = iter_dic.__next__()
    print(res3)
    # 每次取一个值, 取完了没有就会报错
    res4 = iter_dic.__next__()
    print(res4)
    使用迭代器
    dic = {'x':1, 'y':2, 'z':3}
    
    # 注意:这样每次只会取到x,因为每次取值都是从dic去取,不是基于上一次的结果
    print(dic.__iter__().__next__())
    print(dic.__iter__().__next__())
    print(dic.__iter__().__next__())
    注意

    四、for循环的本质

    for循环的本质就是一个迭代器,原理如下:

      1、先调用for语句中in后面的值的 __iter__ 方法,得到迭代器对象

      2、执行迭代器 __next__ 方法得到一个返回值,然后赋值给一个变量,运行循环体代码

      3、循环往复,直到迭代器取值完毕抛出异常,然后捕捉异常自动结束循环

     五、生成器

    常规定义函数,但是,使用yield语句而不是return语句返回结果。yield语句执行一次返回一个结果

    yield关键字:只能用在函数内

    在函数内但凡包含有yield关键字,再去执行函数,就不会立刻运行函数体代码,会得到一个返回值,该返回值成之为生成器对象,生成器本质就是迭代器

    总结 yield:

      1、提供一种自定义迭代器的解决方案

      2、yield可用于返回值,和return相比,相同点是都可以用于返回值,不同点是yield可以暂停函数,可以返回多次值,而return只能返回值一次值函数就立刻终止

    def func():  # 这是一个简单的函数
        a = 1
        return a
    
    print(func())
    
    
    def func():
        print('aaaaaaaaaaa')
        a = 1
        yield a  # 返回第一个值
        print('bbbbbb')
        yield 12  # 返回第二个值
    
    ret = func()        # 得拿到一个生成器
    # print(ret)        # 返回的是一个地址
    print(next(ret))    # 取第一个值
    print(next(ret))    # 取第二个值
    print(next(ret))    # 取第三个值,会报错,因为没有yield第三个值
    初始生成器

    练习:写一个功能,在Python3中实现Python2使用range函数的效果

    Python2中使用 range 会将结果打印出来,Python3则不会

    def my_range(start, stop, step=1):
        while start < stop:
            yield start
            start += step
    
    res = my_range(1, 5, 2)  # 1 3
    
    next(res)
    next(res)
    View Code

    补充:

    三元表达式:将简单的 if--else 语句用一条语句完成

    x = 10
    y = 20
    if x > y:
        res = x
    else:
        res = y
    
    print(res)
    
    # ========================================================================================
    
    x = 10
    y = 20
    res = x if x > y else y
    print(res)
    三元表达式

    列表生成式

    names = ['qiu', 'xi', 'qiuxi', 'zhi', 'fei']
    l = []
    for name in names:
        if name != 'qiu':
            res = '%s_1024' %name
            l.append(res)
    
    print(l)
    
    # ========================================================================================
    
    l = ['%s_1024' %name for name in names if name != 'qiuxi']
    print(l)
    列表生成式

    字典生成式

    items = [('name', 'qiuxi'), ('age', 22), ('sex', 'male')]
    
    dic = {}
    for k, v in items:
        dic[k] = v
    print(dic)
    
    # ========================================================================================
    
    res = {k: v for k, v in items if k != 'sex'}
    print(res)
    字典生成式

    生成器表达式

    res=(i**2 for i in range(3))
    print(res)
    print(next(res))
    print(next(res))
    print(next(res))
    print(next(res))
    生成器表达式
  • 相关阅读:
    Django(四)
    Django(三)
    Django(二)
    Django 基础篇
    jQuery
    JDK,JRE,JVM区别与联系
    webdriver API中文文档
    selenium及webdriver的原理
    JAVA IO流结构图
    抽象工厂与工厂方法的区别
  • 原文地址:https://www.cnblogs.com/qiuxirufeng/p/9724908.html
Copyright © 2011-2022 走看看