【迭代器itrtator、生成器generator】
- 迭代的意思类似于循环,每一次重复的过程被成为一次迭代的的过程,
而每一次迭代得到的结果会被用来下一次迭代的初始值。 - 提供迭代方法的容器成为迭代器
- 通常接触的迭代器有序列(列表、元组、字符串)还有字典也是迭代器,都支持迭代的操作
迭代器:
-
什么是迭代器:
迭代器是指用iter(可迭代对象)函数返回的对象(实例)
迭代器可以用next(it)函数获取可迭代对象的数据 -
迭代器函数:
iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是一个能提供迭代器的可迭代对象
next(iterable)从迭代器iterable中获取下一条记录,如果无法获取下一条记录,则触发StopIteration异常 -
说明:
迭代器是访问可迭代对象的一种方式
迭代器只能向前取值,不会后退
用iter函数可以返回一个可迭代对象的迭代器 -
迭代器的用途:
迭代器对象能用next函数来获取下一个元素 -
示例:
>>> l = [2,3,4,5,6] >>> iter(l) <list_iterator object at 0x02985070> >>> it = iter(l) >>> next(it) 2 >>> next(it) 3 >>> next(it) 4 >>> next(it) 5 >>> next(it) 6 >>> next(it) Traceback (most recent call last): File "<pyshell#8>", line 1, infor i in s: next(it) StopIteration ----------------------------------------------------- # 用while循环语句来访问列表 l = [1,3,5,7,9] it = iter(l) while 1: try: x = next(it) print(x) except StopIteration: print('迭代终止') break -------------------------------------------------------
生成器(Generator)(python2.5及以后)
- 什么是生成器:
1.生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例) - 生成器有两种:
生成器函数
生成器表达式 - 生成器函数定义:
含有yield
语句的函数是生成器函数,此函数被调用时将返回一个生成器对象
注:yield翻译为产生(生成) - 生成器函数说明:
- 生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象
- 再生成器函数调用return时会出现一个StopIteiration异常来通知next(it)函数不会再提供数据
- 基本上不占用计算机的内存空间,很省空间,现调现用
yield语句:
-
语法:
yield表达式 -
说明:
yield用于def函数中,目的是将此函数作为生成器函数使用
yield用来生成数据,供迭代器next(it)函数使用 -
示例:
>>> def myyield(): print('即将生成2') yield 2 print('即将生成3') yield 3 print('即将生成5') yield 5 print('myyield函数返回') >>> it = iter(myyield()) >>> it <generator object myyield at 0x02DCF1B0> >>> next(it) 即将生成2 2 >>> next(it) 即将生成3 3 >>> next(it) 即将生成5 5 >>> next(it) myyield函数返回 Traceback (most recent call last): File "<pyshell#14>", line 1, in <module> next(it) StopIteration
生成器表达式:
- 语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
注:[]里的内容可以省略 - 作用:
用推倒式的形式生成一个新的生成器
列表推倒式
字典推倒式
集合推倒式
元组没有推倒式(用小括号括起来的正是生成器推导式) - 优点:
不占用内存空间
示例:
>>> gen = (x**2 for x in range(1,4))
>>> it = iter(gen)
>>> next(it)
1
>>> next(it)
4
>>> next(it)
9
>>> next(it)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
next(it)
StopIteration
-------------------------------------------------------------
>>> gen
<generator object <genexpr> at 0x02FFF150>
(用小括号括起来的正是生成器推倒式)
-
列表推倒式和生成器表达式的区别:
l = [1,2,3,4] gen = (x for x in l) # gen绑定生成器 lst = [x for x in l] # lst 绑定列表 l[1] = 22 #改变原列表的第二个元素 for x in lst: print(x) # 1 2 3 4 不变 for x in gen: print(x) # 1 22 3 4 第二个数变了
迭代工具函数:
-
作用:
迭代工具函数的作用是生成一个个性化的的迭代对象 -
zip函数:
zip(iter1 [,iter2,iter3,…])
zip()方法用于返回由各个可迭代参数共同组成的元组
返回一个zip对象此对象用于生成一个元组,此元组的个数由最小的可迭代对象决定 -
示例:
>>> l = [1,3,5,7,9] >>> s = 'FishC' >>> t = (2,4,6,8,10,12) >>> for each in zip(l,s,t): print(each) (1, 'F', 2) (3, 'i', 4) (5, 's', 6) (7, 'h', 8) (9, 'C', 10)
-
enumerate(iterable[,start]):
-
enumerate(iterable)方法生成由二元组(二元组就是元素数量为二的元组)构成的一个迭代对象
每个二元组是由可迭代参数的索引号及其对应的元素组成的。 -
生成带索引的枚举对象,返回迭代类型为索引-值对(index,value)
默认索引从0开始,也可以使用start绑定 -
示例:
>>> s = 'FishC' >>> for i in enumerate(s): print(i) (0, 'F') (1, 'i') (2, 's') (3, 'h') (4, 'C') >>> for j in enumerate(s,start = 100): print(j) (100, 'F') (101, 'i') (102, 's') (103, 'h') (104, 'C')
-
示例索引-值对:
def get_lines(): l = [] while 1: s = input('>>>') if not s: break l.append(s) return l def print_text(lst): for numbers,text in enumerate(lst,start = 1): print('第',numbers,'行',text) if __name__ == '__main__': print_text(get_lines())
-
迭代器(高级)
-
什么是迭代器?
可以通过next(obj)函数取值的对象就是迭代器 -
迭代器协议:
迭代器协议是指对象能够使用next函数获取下一项数据
在没有下一项数据时触发一个StopIterator来终止迭代的约定 -
实现方法:
类内需要有__next__(self)方法来实现迭代器协议 -
语法形式:
class MyItorator: def __next__self: 迭代器协议的实现 return 数据
-
什么是可迭代对象?
是指能用iter(obj)函数返回迭代器的对象(实例)
可迭代对象内部一定要定义__iter__(self)方法来返回迭代器
(这个方法实际上就是返回迭代器本身) -
可迭代对象的语法形式:
class MyIterable: def __iter__(self): 语句块 return 迭代器
-
示例:
# 此示例示意可迭代对象和迭代器的定义及使用方法
class MyList:
def __init__(self,iterator):
'''此方法创建一个date实例变量来绑定一个用来存储数据的列表'''
self.date = list(iterator)
def __repr__(self):
'''此方法为了打印此列表的数据'''
return 'MyList(%r)' % self.date
def __iter__(self):
'''有此方法就是可迭代对象,但要求必须返回迭代器'''
print('__iter__方法被调用!')
return MyListIterator(self.date)
class MyListIterator:
'''此类用来创建一个迭代器对象,
用此迭代器对象可以访问MyList类型的数据'''
def __init__(self,iter_date):
self.cur = 0 # 设置迭代器的初始值为0,代表列表的下标
self.it_date = iter_date
# 以上it_date绑定要迭代的列表
def __next__(self):
'''有此方法的对象才叫迭代器
此方法一定要实现迭代器协议'''
print('__next__方法被调用')
# 如果self.cur已经超出了列表的索引范围就报迭代结束
if self.cur >= len(self.it_date):
raise StopIteration
# 否则尚未迭代完成,需要返回数据
r = self.it_date[self.cur] # 拿到要送回去的数
self.cur += 1 # 将当前值向后移动一个单位
return r
myl = MyList([2,3,5,7])
print(myl)
for x in myl:
print(x)
在终端打印:
MyList([2, 3, 5, 7])
__iter__方法被调用!
__next__方法被调用
2
__next__方法被调用
3
__next__方法被调用
5
__next__方法被调用
7
__next__方法被调用