美文网首页
09_Python迭代器_全栈开发学习笔记

09_Python迭代器_全栈开发学习笔记

作者: 豆行僧 | 来源:发表于2019-01-07 23:40 被阅读0次

    1. 迭代器原理

    1.1 dir()

    dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法dir(),该方法将被调用。如果参数不包含dir(),该方法将最大限度地收集参数信息。

    范例1:

    print(dir([]))    # 告诉我列表拥有的所有方法
    print(dir({}))    # 告诉我字典拥有的所有方法
    print(dir(''))    # 告诉我字符串拥有的所有方法
    print(dir(range(10)))    # 告诉我range()拥有的所有方法
    

    执行结果:

    ['__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']
    ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
    ['__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']
    ['__bool__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']
    

    范例2:

    ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10)))
    print(ret)    # 求上述四种类型中共有的方法(求交集)
    

    执行结果:

    {'__contains__', '__sizeof__', '__lt__', '__gt__', '__eq__', '__getitem__', '__class__', '__le__', '__str__', '__new__', '__init_subclass__', '__reduce_ex__', '__dir__', '__reduce__', '__delattr__', '__ne__', '__repr__', '__ge__', '__subclasshook__', '__format__', '__iter__', '__len__', '__doc__', '__init__', '__hash__', '__getattribute__', '__setattr__'}
    

    1.2 双下方法

    范例1:

    print([1].__add__([2]))    # 等同于第二行
    print([1]+[2])    # 等同于第一行
    

    执行结果:

    [1, 2]
    [1, 2]
    

    范例2:
    只要是能被for循环的数据类型 就一定拥有__iter__方法

    # 判断各类型是否含有__iter__方法
    print('__iter__' in dir(int))
    print('__iter__' in dir(bool))
    print('__iter__' in dir(list))
    print('__iter__' in dir(dict))
    print('__iter__' in dir(set))
    print('__iter__' in dir(tuple))
    print('__iter__' in dir(enumerate([])))
    print('__iter__' in dir(range(1)))
    

    执行结果:

    False
    False
    True
    True
    True
    True
    True
    True
    

    1.3 引出迭代器

    一个列表执行了__iter__()之后的返回值就是一个迭代器
    范例1:

    print([].__iter__())
    

    执行结果:

    <list_iterator object at 0x000001A65E641898>
    

    范例2:
    查看两者的方法

    print(dir([]))
    print(dir([].__iter__()))
    

    执行结果:

    ['__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']
    ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
    

    范例3:
    查看迭代器独有的方法

    print(set(dir([].__iter__())) - set(dir([])))
    
    print([1,'a','bbb'].__iter__().__length_hint__())  #元素个数
    
    l = [1,2,3]
    iterator = l.__iter__()
    print(iterator.__next__()) # 用__next__方法一个一个取值
    print(iterator.__next__())
    print(iterator.__next__())
    

    执行结果

    {'__setstate__', '__next__', '__length_hint__'}
    
    3
    
    1
    2
    3
    

    1.4 小结与概念

    Iterable 可迭代的 -- > __iter__ #只要含有__iter__方法的都是可迭代的
    [].__iter__() 迭代器 -- > __next__ #通过next就可以从迭代器中一个一个的取值

    可迭代协议:只要含有 __iter__ 方法的都是可迭代的
    迭代器协议:内部含有 __next____iter__ 方法的就是迭代器

    1.4.1 证明迭代器协议

    范例1:

    print('__iter__' in dir( [].__iter__()))
    print('__next__' in dir( [].__iter__()))
    

    执行结果:

    True
    True
    

    范例2:
    isinstance()方法

    from collections import Iterable    # 可迭代的
    from collections import Iterator    # 迭代器
    print(isinstance([],Iterator))    # 使用isinstance判断列表是不是一个迭代器
    print(isinstance([],Iterable))    # 使用isinstance判断列表是不是一个可迭代的
    

    执行结果:

    False    # 列表不是迭代器
    True    # 列表是可迭代的
    

    1.5 可迭代概念

    迭代器协议 —— 内部含有 __next____iter__ 方法的就是迭代器

    迭代器协议和可迭代协议
    可以被for循环的都是可迭代的
    可迭代的内部都有 __iter__ 方法
    只要是迭代器 一定可迭代
    可迭代的 .__iter__() 方法就可以得到一个迭代器
    迭代器中的 __next__() 方法可以一个一个的获取值

    for循环其实就是在使用迭代器

    判断别人写的函数是否是迭代器

    1. iterator
      print([].iter())
    1. 可迭代对象
      print(range(10))
    1. 直接给你内存地址

    for
    只有 是可迭代对象的时候 才能用for
    当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代

    范例:
    for循环做得事情(for循环的工作原理)

    for i in l:
        pass
    
    # for循环实际工作步骤如下:
    # iterator = l.__iter__()
    # iterator.__next__()
    

    1.6 迭代器的好处

    1. 从容器类型中一个一个的取值,会把所有的值都取到。
    2. 节省省内存空间(range与文件句柄)
         迭代器并不会在内存中再占用一大块内存,
            而是随着循环每次生成一个;
            每次next每次给我一个。

    1.7 模仿for循环写自己的迭代器例子

    范例:

    l = [1,2,3,45]
    iterator = l.__iter__()
    while True:
        print(iterator.__next__())
    

    执行结果:

    1
    Traceback (most recent call last):
    2
      File "E:/python_project/muggle/muggle_test.py", line 6, in <module>
    3
    45
        print(iterator.__next__())
    StopIteration
    # 上述报错为正常,以后会学到如何消除报错
    

    2. 迭代器复习

    # 迭代器和生成器
    # 迭代器
        # 可迭代协议 —— 含有iter方法的都是可迭代的
        # 迭代器协议 —— 含有next和iter的都是迭代器
        # 特点
            # 节省内存空间
            # 方便逐个取值,一个迭代器只能取一次。
    

    相关文章

      网友评论

          本文标题:09_Python迭代器_全栈开发学习笔记

          本文链接:https://www.haomeiwen.com/subject/rhsmrqtx.html