python中的for 循环
s=[1,2,3,4] for i in s: print(i)
一、可迭代
字符串,列表,集合,字典,元组这些都可以被for循环,说明他们是可迭代的
迭代就是:将某个数据集内的数据一个挨着一个的取出来,就叫做可迭代
可迭代对应的标志:_iter_
print('__iter__' in dir([1,2,3])) #判断一个变量是不是一个可迭代的
二、迭代协议
希望这个数据类型里的东西也可以使用for被一个一个的取出来,那我们就必须满足for的要求。
这个要求就叫做“协议”。
l= [1,2,3,4,5] for i in l: print(i) print(iter(l)) #内置函数
可迭代协议——凡是可迭代的内部都有一个__iter__方法
三、迭代器协议
迭代器协议 : 内部实现了__iter__ __next__方法
迭代器里既有iter方法,又有next方法 ——迭代器协议
通过iter(o)得到的结果就是一个迭代器,
o是一个可迭代的
l = [1,2,3,4,5] l_iterator = iter(l) print(l_iterator.__next__()) print(l_iterator.__next__()) print(l_iterator.__next__()) print(l_iterator.__next__()) print(l_iterator.__next__()) next(l_iterator) #==l_iterator.__next__() while True: try: print(next(l_iterator)) except StopIteration: break
迭代器 大部分都是在python的内部去使用的,我们直接拿来用就行了
迭代器:内置__iter__和__next__方法
迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。
s = 'abc' print(isinstance(s,Iterable)) print(isinstance(s,Iterator)) print(isinstance(iter(s),Iterator))
不管是一个迭代器还是一个可迭代对象,都可以使用for循环遍历
迭代器出现的原因 帮你节省内存
from collections import Iterable from collections import Iterator a = range(100) print(isinstance(a,Iterable)) print(isinstance(a,Iterator))
可迭代和迭代器的不同点 : 迭代器多实现了一个__next__方法
可迭代和迭代器的相同点 : 都可以用for循环
判断迭代器和可迭代的方法
第一种:判断内部是不是实现了 __next__
'__next__' in dir(o)
第二种:
from collections import Iterable #可迭代 from collections import Iterator #迭代器 isinstance(o,Iterable) isinstance(o,Iterator)
四:生成器
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,
挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
五、生成器函数
def func(): print('aaaa') a = 1 yield a #返回第一个值 print('bbbb') yield 12 #返回第二个值 ret = func() #拿到一个生成器 print(ret) print(next(ret)) #取第一个值 print(next(ret)) #取第二个值 print(next(ret)) #取第三个值 会报错 因为没有第三个值
def make_cloth(): for i in range(2000000): yield "第%s件衣服"%i szq = make_cloth() print(next(szq)) print(next(szq)) print(next(szq)) for i in range(50): print(next(szq))
def tail(filename): with open(filename) as f: f.seek(0, 2) #从文件末尾算起 while True: line = f.readline() # 读取文件中新的文本行 if not line: time.sleep(0.1) continue yield line for line in tail('tmp_file'): print(line,end = '')
def averager(): total = 0 day = 0 avrage = 0 while True: day_num = yield avrage #return avrage total += day_num day += 1 avrage = total/day avg = averager() num = next(avg) #激活生成器 avg.send(),什么都不send和next效果一样 print(avg.send(10)) #传值 next print(avg.send(20))
六、列表式推导
for i in range(100): print(i*i)
l =[i*i for i in range(100)] print(l)
l = [{'name':'v','age':28},{'name':'v'}] name_list = [dic['name'] for dic in l] print(name_list)
l = [{'name':'v1','age':28},{'name':'v2'}] name_list_generator = (dic['name'] for dic in l) print(name_list_generator) print(next(name_list_generator)) print(next(name_list_generator))
laomuji = ('鸡蛋%s' %i for i in range(1,11)) print(laomuji) print(next(laomuji)) print(next(laomuji))