迭代器及生成器
迭代器
内部含有_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']TrueTrue{ '__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 Iterablefrom collections import Iteratorprint(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)
生成器
自己想写个可迭代的,---生成器 生成器的本质就是迭代器 因此生成器的所有好处都和迭代器一样 但是生成器是我们自己写的python代码 生成器的实现由两种方式:1.生成器函数,2.生成器表达式
def g_func(): yield 1g = g_func()print(g)# generator 生成器 本质还是迭代器print(g.__next__())
生成器函数和普通函数之间的区别 生成器函数中含有yield关键字 生成器函数调用的时候不会立即执行,而是返回一个生成器
def g_func(): for i in range(2000): yield ig = g_func()print(g.__next__())print(g.__next__())print(g.__next__())
例题
def cloth(): for i in range(1000): yield '衣服%s'%ig = cloth()for i in range(50): print(g.__next__())