一个对象实现了__iter__()方法,就是可迭代对象。咱们经过两种方法判断str、tuple、range、list、set、dict类型的容器是否为可迭代对象。一种方法是经过dir()函数查看目标对象是否具备__iter__()方法;另外一种方法是从collections模块中导入Iterable属性,利用isinstance()函数判断目标对象是否为Iterable类型,若是是的话,该目标对象即为可迭代对象。python
s = 'my name is david' #str类型 t = (1,2,3,'a','5') #tuple类型 r = range(10) #range类型 l = [1,2,3,4,5] #list类型 st = {'a','b','c',4,5} #set类型 d = {'a':1,'b':2,'c':3,'d':4} #dict类型 from collections import Iterable #使用Iterable属性判断目标对象是否为可迭代对象 print(isinstance(s,Iterable)) print(isinstance(t,Iterable)) print(isinstance(r,Iterable)) print(isinstance(l,Iterable)) print(isinstance(st,Iterable)) print(isinstance(d,Iterable))
一个对象同时实现了__iter__()方法与__next__()方法,就是迭代器。为了更直观地感觉迭代器,咱们自定义一个斐波那契数列类Fib,将该类实例化以后能够生成迭代器。socket
class Fib: def __init__(self): self.prev = 0 self.curr = 1 def __iter__(self): #一个对象实现__iter__()方法,就是可迭代对象。 return self def __next__(self): #一个可迭代对象实现__next__()方法,就是迭代器。 value = self.curr self.curr += self.prev self.prev = value return value f = Fib() from collections import Iterable, Iterator print(isinstance(f,Iterable)) #f既是可迭代对象 print(isinstance(f,Iterator)) #f也是迭代器
在这里,咱们经过创建一个Fib类,而后实例化为一个f对象的形式自定义一个迭代器。能够说自定义迭代器的方式是比较笨拙的,后面咱们会介绍生成器,与迭代器相比,自定义生成器是比较简洁、优雅的。函数
迭代器不会一次性将全部的元素都加载到内存,等到使用next()调用的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。itertools模块中的函数返回的都是迭代器对象。工具
from collections import Iterator from itertools import count counter = count(start=13) print(isinstance(counter,Iterator)) from itertools import cycle colors = cycle(['red','yellow','blue']) print(isinstance(colors,Iterator)) from itertools import islice iterslice = islice(counter,2,12) print(isinstance(iterslice,Iterator))
使用python内置函数iter()能够将可迭代对象变成迭代器。code
from collections import Iterator s = 'my name is david' #str类型 t = (1,2,3,'a','5') #tuple类型 r = range(10) #range类型 l = [1,2,3,4,5] #list类型 st = {'a','b','c',4,5} #set类型 d = {'a':1,'b':2,'c':3,'d':4} #dict类型 si = iter(s) print(isinstance(si,Iterator)) ti = iter(t) print(isinstance(ti,Iterator)) ri = iter(r) print(isinstance(ri,Iterator)) li = iter(l) print(isinstance(li,Iterator)) sti = iter(st) print(isinstance(sti,Iterator)) di = iter(d) print(isinstance(di,Iterator))
Python 3中关于iter(object[, sentinel])方法有两个参数。 使用iter(object)这种形式比较常见。 iter(object, sentinel)这种形式通常较少使用,Python的文档说明貌似也不容易理解。对象
生成器(generator)是一种特殊的迭代器,与迭代器相比,生成器更为优雅。它不须要再像上面的类同样写__iter__()和__next__()方法,只须要一个yiled关键字,像定义函数同样自定义生成器。咱们建立了一个生成器后,基本上永远不会调用next()方法,而是经过for循环来迭代它。 与自定义迭代器相比,下面这种使用生成器来建立斐波那契数列的方式是否是更优雅?内存
def fib(): prev, curr = 0, 1 while True: yield curr prev, curr = curr, curr + prev f = fib() #建立迭代器 from itertools import islice #导入迭代器切片工具 list(islice(f,0,10))
此外,咱们还可使用生成器表达式来构造生成器。与列表生成式相似,只须要把一个列表生成式的[]改为(),就能够建立一个生成器。文档
>>> 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 0x0000026428DEC308>