迭代器,生成器
1生成器是特殊的迭代器,
2爹带起有个特点是能调用next和iter方法。(py2和py3中略有不同,py2的方法名是__iter__和next(),而py3中的方法名是__iter__和__next__)
3含有iter方法的是可迭代对象,并且该iter方法会返回iter和next方法均具备的迭代器。list就是是可迭代对象,但是list等并不是迭代器,因为他没有内置next方法
4 for xxx in list ,这里有一个隐式转化,会先将list转为迭代器
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x104feab40>
也就是说[x for x in range(10)]是列表,(x for x in range(10))是生成器
生成器有两种实现方式:一种是上述这个,一种是有yield语句的函数
特别的[x for x in range(10) if x>5]结果是[6,7,8,9]
可迭代对象和迭代器:
可迭代对象内包含__iter__方法,该方法返回迭代器。
而迭代器是包含next方法和__iter__方法,__iter_方法返回其自身(经测试不包含__iter__不行)
可迭代对象:
class Iterable_:
def __iter__(self):
print ("haha")
return iter([1, 2, 3])
for i in Iterable_():
print "iterable:" + str(i)
#输出
haha
iterable:1
iterable:2
iterable:3
迭代器是:
class Iterator_:
def __init__(self, s, e):
self.current = s
self.end = e
def __iter__(self):
return self
def next(self):
if self.current < self.end:
self.index = self.current
self.current += 1
return self.index
else:
raise StopIteration
it = Iterator_(5, 8)
for i in it:
print "iterator:" + str(i)
#never print
for i in it:
print "second iterator:" + str(i)
#print again
it = Iterator_(5, 8)
for i in it:
print "second iterator:" + str(i)
#输出
iterator:5
iterator:6
iterator:7
second iterator:5
second iterator:6
second iterator:7
总结一下:迭代器和生成器均含有iter()和next(),其中iter方法是返回其自身。二者的区别是迭代器需要我们手动创建类,类中要实现iert和next方法,迭代器就是该类的对象。而生成器就要简单一些,不必实现以上二者方法,只需要将一个函数的return改为yield,那么该函数返回的将是一个生成器,或者可以用生成式生成。而可迭代对象是只含有iter(),并且这个iter的功能是返回一个迭代器
生成器在python2,python3中的区别,原因未知:
在python2中,定义生成器的函数中,不能return某个值,包括None值也不行,比如return 1,return None,只可以单独一个return,后面不接任何返回值
而在python3中却没有这方面的避讳,但是没什么意义,因为在用for循环的时候,无法拿到我们定义的返回值,除非,我们捕获StopIteration异常
1 def fib(max): 2 n= 0 3 b=1 4 while n < max: 5 yield b 6 n = n + 1 7 return 'done' 8 for i in fib(3): 9 print (i) 10 11 """输出结果: 12 1 13 1 14 1 15 """ 16 #除非我们捕获异常: 17 g = fib(3) 18 while True: 19 try: 20 x = next(g) 21 print(x) 22 except StopIteration as e: 23 print('Generator return value:', e.value) 24 break 25 26 """输出结果: 27 1 28 1 29 1 30 Generator return value: done 31 """