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

    迭代器及生成器

    迭代器

    内部含有_iter_方法的数据类型,就是可迭代的,
    如:
    print('_iter_' in dir('abc'))的执行结果如下:(请看是否有_iter_)

    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    #迭代器比可迭代的多一个_next_方法
    #迭代器:包含_next_,_iter_方法的就是迭代器
    #包含_next_方法的可迭代对象就是迭代器
    l = [1,2,3,4,5]
    lst_iter = l.__iter__()
    print(dir(l))
    print('__iter__' in dir(lst_iter))
    print('__next__' in dir(lst_iter))
    print(set(dir(lst_iter)) - set(dir(l)))
    lst_iter.__next__()
    
    执行结果如下:
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    True
    True
    {'__length_hint__', '__next__', '__setstate__'}
    # 例题:
    # l = ['ha','hei','he']
    # lst_iter = l.__iter__()
    # print(lst_iter.__next__())
    # print(lst_iter.__next__())
    # print(lst_iter.__next__())
    可迭代的 必须含有_iter_方法     #可迭代协议
    迭代器比可迭代的多了一个_next_方法
    迭代器:包含_next_,_iter_方法 #迭代器协议
    包含_next_方法的可迭代对象就是迭代器
    迭代器是可迭代的一部分
    获得迭代器:可迭代的调用_iter_()
    使用迭代器:迭代器_next_()
    如何判断一个变量是不是迭代器或者可迭代的
    方法一:
    print('_iter_' in dir([1,2,3,4]))
    print('_next_' in dir([1,2,3,4]))
    方法二:
    from collections import Iterable
    from collections import Iterator
    print(isinstance([1,2,3,4,5],Iterable))
    str_iter = 'abc'.__iter__()
    print(isinstance(str_iter,Iterator))
    print(isinstance('abc',Iterator))
    迭代器的特点:
    惰性运算(要的时候才给,不要不给)
    从前到后一次去取值,过程不可逆,不可重复
    节省内存
    用while循环模拟for循环的方法:
    l = [1,2,3,4,5]
    l_iter = l.__iter__()
    while True:
        try:
            print(l_iter.__next__())
        except StopIteration:
            break
    for 循环是让我们更简单的使用迭代器
    用迭代器去值就不需要关心索引或者key的问题了
    目前我们已知的可迭代的都是python提供给我们的(range(),f这里指的是文
    件,enumerate()指的是枚举)

    一个对象要想被for循环,这个对象如果有个__iter__方法,必须得返回一个迭代器.
    # class Foo(object):
    #     pass
    #
    # obj=Foo()
    # for item in obj:
    #     print(item)
    
    # 要想被for循环,内部必须有iter方法
    
    
    class Foo(object):
        def __iter__(self):
            return iter([1,2,3,4,5])        #列表是可迭代对象,iter(可迭代对象)就变成了迭代器
    
    obj=Foo()
    for item in obj:
        print(item)
    对象想要被for循环,内部需要有一个__iter__方法,并返回一个迭代器
    
    
    


    生成器
    自己想写个可迭代的,---生成器
    生成器的本质就是迭代器
    因此生成器的所有好处都和迭代器一样
    但是生成器是我们自己写的python代码
    生成器的实现由两种方式:1.生成器函数,2.生成器表达式
    def g_func():
        yield 1
    
    g = g_func()
    print(g)
    # generator  生成器  本质还是迭代器
    print(g.__next__())
    生成器函数和普通函数之间的区别
    生成器函数中含有yield关键字
    生成器函数调用的时候不会立即执行,而是返回一个生成器
    def g_func():
        for i in range(2000):
            yield i
    
    g = g_func()
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())

    例题

    def cloth():
        for i in range(1000):
            yield '衣服%s'%i
    
    g = cloth()
    for i in range(50):
        print(g.__next__())
  • 相关阅读:
    函数的命名空间和作用域
    python 各个地方导航(方便查询,持续更新!)
    零基础学虚幻4(UE4):蓝图+VR 丁树凯教程
    UE4打包后的游戏,无法打卡其他关卡的解决办法
    【精辟】进制转换
    Git仓库的初始化
    【编程】杂碎知识点
    MFC制作带界面的DLL库
    StartImage.DLL使用说明
    MFC对话框程序:实现程序启动画面
  • 原文地址:https://www.cnblogs.com/dwenwen/p/7780272.html
Copyright © 2011-2022 走看看