Python中的iterable object(可迭代对象)是指存储了元素的容器对象,并且该容器对象实现了__iter__()方法,容器对象中的元素可以通过__iter__()方法访问。
class UserDefine(object):
def __init__(self, data):
self.data = data
def __iter__(self):
return iter(self.data)
#def __getitem__(self, index):
# return self.data[index]
it_ob = [1, 2, 3, 4, 5]
user_define = UserDefine(it_ob)
import collections
print(isinstance(user_define,collections.Iterable))
print(isinstance(user_define,collections.Iterator))
for i in user_define:
print(i)
上面代码中如果把__iter__()注释掉而改为实现已经注释了的__getitem__(),则同样可以使用for…in遍历user_define的元素,但是调用isinstance判断是否为Iterable时返回False。所以iterable object可以通过for…in循环遍历元素,但是可以通过for…in循环遍历元素的不一定是iterable object。
Python中的iterator(迭代器)是指存储了元素的容器对象,并且该容器对象同时实现了__iter__()和__next__()方法,每次调用该容器对象返回自身的下一个元素。其中__iter__()方法返回对象自身(对象自身必须为迭代器),而__next__()方法则显式得返回下一个元素。
当使用for…in循环遍历iterable object时实际包含2个操作:1、调用__iter__()返回一个迭代器,2、不断调用__next__()获取下一个元素直到返回StopIteration。
class UserDefine(object):
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
self.index = 0
return self
def __next__(self):
if self.index > len(self.data)-1:
raise StopIteration
out_data = self.data[self.index]
self.index += 1
return out_data
it_o = [1, 2, 3, 4, 5]
user_define = UserDefine(it_o)
import collections
print(isinstance(user_define,collections.Iterable))
print(isinstance(user_define,collections.Iterator))
for i in user_define:
print(i)
generator是Python的一种一边循环一边计算的机制。generator是一种特殊的迭代器,自动实现了"迭代器协议"(即__iter__()和__next__()方法),不需要再显式得实现这2个方法。创建方式主要有2种:
列表生成式的[]改成()
it_ob = [0,1,2,3,4]
gen = (i for i in it_ob)
import collections
print(isinstance(gen,collections.Iterable))
print(isinstance(geb,collections.Iterator))
for i in gen:
print(i)
在函数中添加yield语句
def gen(num):
i = 0
while i < num:
yield i
i += 1
g = gen(5)
import collections
print(isinstance(g,collections.Iterable))
print(isinstance(g,collections.Iterator))
for i in g:
print(i)
generator允许使用send()在迭代过程中对当前迭代值进行修改,如下:
def gen(num):
i = 0
while i < num:
rec = yield i
i = i + 1 if rec is None else rec
g = gen(5)
print(next(g))
print(next(g))
g.send(0)
print(next(g))
print(next(g))