如果列表元素可以按照某种算法推算出来,可以在循环的过程中不断推算出后续的元素。这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
#将列表生成式的[]改为()得到generator,通过for循环得到generator的下一个返回值 g=(x*x for x in range (10)) for n in g: print(n)
#用函数表示斐波那契数列的前n个数 def fib(n): m,a,b=0,0,1 while m<n: print(b) a,b=b,a+b m=m+1 return 'done' print(fib(6))
可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
#使用isinstance()判断一个对象是否是Iterable对象 from collections import Iterable print(isinstance([],Iterable)) print(isinstance({},Iterable)) print(isinstance('abc',Iterable)) print(isinstance('100',Iterable)) print(isinstance((x for x in range(10)), Iterable))
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
#使用isinstance()判断一个对象是否是Iteratro对象 from collections import Iterator print(isinstance((x for x in range(10)),Iterator)) print(isinstance([], Iterator)) print(isinstance({},Iterator)) print(isinstance('abc',Iterator))
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
#使用iter()函数把list、dict、str等Iterable变成Iterator from collections import Iterator print(isinstance(iter([]),Iterator)) print(isinstance(iter({}),Iterator)) print(isinstance(iter('abc'),Iterator))
Python的Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
Python的for
循环本质上就是通过不断调用next()
函数实现的
看看天上,于是我去了满是风雪的地方