09_Python迭代器_全栈开发学习笔记
2019-01-07 本文已影响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循环其实就是在使用迭代器
判断别人写的函数是否是迭代器
- iterator
print([].iter())
- 可迭代对象
print(range(10))
- 直接给你内存地址
for
只有 是可迭代对象的时候 才能用for
当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代
范例:
for循环做得事情(for循环的工作原理)
for i in l:
pass
# for循环实际工作步骤如下:
# iterator = l.__iter__()
# iterator.__next__()
1.6 迭代器的好处
- 从容器类型中一个一个的取值,会把所有的值都取到。
- 节省省内存空间(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的都是迭代器
# 特点
# 节省内存空间
# 方便逐个取值,一个迭代器只能取一次。