一:可迭代对象(Iterable)
可迭代对象是只有__iter__方法的对象,可以使用for循环来遍历。字符串、列表、元组、字典、几何、文件都是迭代对象。
二:迭代器(Iterator)
迭代器是同时有__iter__与__next__方法。可迭代对象通过__iter__即可得到一个迭代器
1 ''' 2 dir([1,2].__iter__())是列表迭代器中实现的所有方法,dir([1,2])是列表中实现的所有方法,都是以列表的形式返回给我们的,为了看的更清楚,我们分别把他们转换成集合,然后取差集。 3 ''' 4 #print(dir([1,2].__iter__())) 5 #print(dir([1,2])) 6 print(set(dir([1,2].__iter__()))-set(dir([1,2]))) 7 8 结果: 9 {'__length_hint__', '__next__', '__setstate__'}
1 iter_l = [1,2,3,4,5,6].__iter__() 2 #获取迭代器中元素的长度 3 print(iter_l.__length_hint__()) 4 #根据索引值指定从哪里开始迭代 5 print('*',iter_l.__setstate__(4)) 6 #一个一个的取值 7 print('**',iter_l.__next__()) 8 print('***',iter_l.__next__())
三:容错的方法
try: else: 语句,会把报错的语句列出来,程序不会报错
1 l = [1,2,3,4] 2 l_iter = l.__iter__() 3 while True: 4 try: 5 item = l_iter.__next__() 6 print(item) 7 except StopIteration: 8 break
四:判断一个对象是可迭代对象与可迭代器方法
1 from collections import Iterable 2 from collections import Iterator 3 4 print(isinstance(range(100),Iterator)) 5 print(isinstance(range(100),Iterable))
五:使用while来实现for循环
1 l=[1,2,3] 2 3 index=0 4 while index < len(l): 5 print(l[index]) 6 index+=1
六:生成器(Generator)
生成器的本质即是写程序人员写的迭代器。生成器的本质就是一个迭代器,可以节省内存。用yield语句来一次返回一个结果,每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
关键字yield与return不同,yield的作用是得到一个迭代器,把函数停止,但还可以继续执行;return的作用是返回函数值,即结束就函数。
1 import time 2 def genrator_fun1(): 3 a = 1 4 print('现在定义了a变量') 5 yield a 6 b = 2 7 print('现在又定义了b变量') 8 yield b 9 10 g1 = genrator_fun1() 11 print('g1 : ',g1) #打印g1可以发现g1就是一个生成器 12 print('-'*20) #我是华丽的分割线 13 print(next(g1)) 14 time.sleep(1) #sleep一秒看清执行过程 15 print(next(g1))
实例:
1 import time 2 3 4 def tail(filename): 5 f = open(filename) 6 f.seek(0, 2) #从文件末尾算起 7 while True: 8 line = f.readline() # 读取文件中新的文本行 9 if not line: 10 time.sleep(0.1) 11 continue 12 yield line 13 14 tail_g = tail('tmp') 15 for line in tail_g: 16 print(line) 17 18 生成器监听文件输入的例子
1 import time 2 3 4 def tail(filename): 5 f = open(filename) 6 f.seek(0, 2) #从文件末尾算起 7 while True: 8 line = f.readline() # 读取文件中新的文本行 9 if not line: 10 time.sleep(0.1) 11 continue 12 yield line 13 14 tail_g = tail('tmp') 15 for line in tail_g: 16 print(line) 17 18 生成器监听文件输入的例子
1 def init(func): #在调用被装饰生成器函数的时候首先用next激活生成器 2 def inner(*args,**kwargs): 3 g = func(*args,**kwargs) 4 next(g) 5 return g 6 return inner 7 8 @init 9 def averager(): 10 total = 0.0 11 count = 0 12 average = None 13 while True: 14 term = yield average 15 total += term 16 count += 1 17 average = total/count 18 19 20 g_avg = averager() 21 # next(g_avg) 在装饰器中执行了next方法 22 print(g_avg.send(10)) 23 print(g_avg.send(30)) 24 print(g_avg.send(5)) 25 26 计算移动平均值(2)_预激协程的装饰器
yield from
1 def gen1(): 2 for c in 'AB': 3 yield c 4 for i in range(3): 5 yield i 6 7 print(list(gen1())) 8 9 def gen2(): 10 yield from 'AB' 11 yield from range(3) 12 13 print(list(gen2())) 14 15 yield from
七:列表推导式和生成器表达式
1 l = [i*i for i in range(100)] 2 print(l) 3 4 5 l = [{'name':'v1'},{'name':'v2'}] 6 name_list = [dic['name'] for dicin l]
1 #老男孩由于峰哥的强势加盟很快走上了上市之路,alex思来想去决定下几个鸡蛋来报答峰哥 2 3 egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析 4 5 #峰哥瞅着alex下的一筐鸡蛋,捂住了鼻子,说了句:哥,你还是给我只母鸡吧,我自己回家下 6 7 laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式 8 print(laomuji) 9 print(next(laomuji)) #next本质就是调用__next__ 10 print(laomuji.__next__()) 11 print(next(laomuji)) 12 13 峰哥与alex的故事
把列表推导式的中括号改为小括号即变为生成器表达式。生成器表达式更节省内存空间。
浙公网安备 33010602011771号