1,什么是可迭代对象。
for 循环,可以循环的就是可迭代对象。字符串string,列表list ,字典dict,集合set ,range.
内部含有_iter_方法的对象,就叫可迭代对象。可迭代对象就遵循可迭代协议。dir以下所有含的方法
s = 'dashfhk' print(dir(s)) # ['__add__', '__class__', '__contains__', '__delattr__', # '__dir__', '__doc__', '__eq__', '__format__', '__ge__', # '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', # '__init__', '__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']
如何判断?
li = [1,2,3,44,55,5] print('__iter__'in dir(li)) li = (1,2,3,44,55,5) print('__iter__'in dir(li)) from collections import Iterable li = [1,2,34,5,6] print(isinstance(li,Iterable)) print(isinstance(li,list))
如果含有_iter_就可以for 循环。
2,迭代器
什么叫做迭代器?迭代器英文意思是iterator。可迭代对象转化成迭代器,可迭代对象._iter_()。
迭代器含有 _iter_ 和_next_,迭代器也要遵循迭代器协议。
如何判断什么是迭代器?
li = [34, 45, 67, 77] l2 = li.__iter__() l3 = l2.__next__() print(l3) l3 = l2.__next__() print(l3) l3 = l2.__next__() print(l3) l3 = l2.__next__() print(l3) from collections import Iterator li = [34, 45, 67, 77] l2 = li.__iter__() print(isinstance(l2,Iterator))
迭代器有什么特点:1,节省内存空间。2,满足惰性机制。3,不能反复取值,不可逆。
用 while 循环模拟 for 取值
l2 = [2, 4, 5, 9, 6, 7, 32] li_obj = l2.__iter__() while True: try: i = li_obj.__next__() print(i) except StopIteration: break l2 = [1, 4, 5, 6, 7] li_obj = l2.__iter__() while True: try: i = li_obj.__next__() print(i) except Exception: break
3,生成器 ,生成器本质上是迭代器。
生成器的产生方式:1,生成器函数构造。2,生成器推导式构造。3,数据类型的转化。
第一,函数中只要有yield,那他就不是一个函数,而是一个生成器。
第二,g 称作生成器对象。
一个__next__对一个yield取值。
next和send功能一样,都是执行一次,send可以给上一个yield赋值,最后一个yield不能赋值。
def func1(): for i in range(1,1000): yield '老男孩校服%d号'% i g = func1() for i in range(50): g.__next__() for j in range(150): print(g.__next__())
def generator(): print(123) content = yield 1 print(content) print(456) yield 2 g = generator() g.__next__() print('***') ret = g.send('hello') #send的效果和next一样 print('***',ret)
#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
# 第一次使用生成器的时候 是用next获取下一个值
# 最后一个yield不能接受外部的值