一:可迭代对象(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__())
View Code

三:容错的方法

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
try else

四:判断一个对象是可迭代对象与可迭代器方法

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
View Code

六:生成器(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
View Code

七:列表推导式和生成器表达式

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的故事
View Code

把列表推导式的中括号改为小括号即变为生成器表达式。生成器表达式更节省内存空间。