容器和迭代部分引自老猿python,写的很赞!感谢
一、容器
容器就是把多个数据类型组织到一起的数据结构。如python内置数据类型list,dict,tuple等。容器仅仅只是用来存取数据的,不具备取出操作功能。正是可迭代对象赋予容器这种能力。迭代的取出数据,不断拿出下一个元素。
二、什么是迭代。
迭代不同于循环,迭代指重复进行某种操作,并且当前操作依赖于上次操作(如版本迭代,模型优化迭代,在上一次基础上进行)。如:
#1) 非迭代例子
loop = 0
while loop < 3:
print("Hello world!")
loop += 1
#2) 迭代例子
loop = 0
while loop < 3:
print(loop)
loop += 1
#例1仅是循环3次输出" Hello world!",输出的数据不依赖上一次的数据,因此不是跌代。
三、迭代器和可迭代对象
Python中迭代器和可迭代对象并不是指某种特定数据类型。而是指实现了某种协议。如。实现了迭代器协议的对象就是迭代器。
先给出定义:
实现了__iter__协议的对象是可迭代对象
实现了__next__协议的对象是迭代器
注意:一个迭代器本身是不能独自进行迭代的。需要用for … in来完成迭代。凡是可迭代的对象都可以用for … in 循环访问。(能用于for … in的是可迭代对象)
1.可迭代对象
调用__iter__方法返回一个迭代器。
2.迭代器
__next__每次调用返回下一个元素。返回StopIteration错误时终止迭代。
先列举一个极端的例子验证迭代器与生产器。迭代器返回的并不是容器中元素。
#%%
class MyIter():
"""定义一个迭代器"""
def __init__(self):
self.start = 0
def __next__(self):
self.start += 2
if self.start < 100:
return self.start
else:
raise StopIteration
t3 = MyIter()
class MyIteralbe():
"""定义一个可迭代对象"""
def __iter__(self):
return t3
t4 = MyIteralbe()
for i in t4:
print(i)
运行结果:
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
52
54
56
58
60
62
64
66
68
70
72
74
76
78
80
82
84
86
88
90
92
94
96
98
t3实现了__next__协议是一个迭代器。T4实现了__iter__方法返回t3,是一个可迭代的对象。同时t4可用于for … in 循环中。
for …in循环做的事情就是不断的拿出迭代器中下一个元素,直到抛出StopIteration异常。
同时可验证直接将迭代器用于for…in会报错。
之所以要实现迭代器的目的就是循环访问容器中的元素。上面的例子是自己另外定义了一个迭代器。一般都是一个容器同时生成__iter__和__iter__协议。
class MyContainer():
def __init__(self):
self.data = [0,1,2,3,4]
self.idx = -1
def __iter__(self):
return self#返回自身,因为自身实现了__next__协议,是一个迭代器。
def __next__(self):
if (self.idx + 1) >= len(self.data):
raise StopIteration
else:
self.idx += 1
return self.data[self.idx]
t5 = MyContainer()
for i in t5:
print(i)
运行结果:
0
1
2
3
4
3.生成器
对于生成器,python会自动生成迭代器相关协议。
所以生成器也是一种迭代器,具有和生成器一样的特性,不断生成next元素。
Python中两种方式构建生成器。
生成器函数:用yield替换return。每次调用返回数据,并且保存函数状态。
生成器表达式:(I for I in xrange(10000000000))