这篇文章给大家分享的是有关Python中可迭代对象、迭代器、For循环工作机制、生成器的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
1.iterable iterator区别
要了解两者区别,先要了解一下迭代器协议:
迭代器协议是指:对象需要提供__next__()方法,它返回迭代中的元素,在没有更多元素后,抛出StopIteration异常,终止迭代。
可迭代对象就是:实现了迭代器协议的对象。
协议是一种约定,可迭代对象实现迭代器协议,Python的内置工具(如for循环,sum,min,max函数等)通过迭代器协议访问对象,因此,for循环并不需要知道对象具体是什么,只需要知道对象能够实现迭代器协议即可。
迭代器(iterator)与可迭代对象(iterable)并不是同一个概念。
直观上:
1.可迭代对象(iterable):凡是具有__iter__的方法的类,都是可迭代的类。可迭代类创建的对象实现了__iter__方法,因此就是可迭代对象。用list、tuple等容器创建的对象,都是可迭代对象。可迭代对象通过__iter__方法返回一个迭代器,然后在内部调用__next__方法进行迭代,最后没有元素时,抛出异常(这个异常python自己会处理,不会让开发者看见)。
2.迭代器(iterator):迭代器对象必须同时实现__iter__和__next__方法才是迭代器。对于迭代器来说,__iter__ 返回的是它自身 self,__next__ 则是返回迭代器中的下一个值,最后没有元素时,抛出异常(异常可以被开发者看到)。
从上面2点可以看出:
1.迭代器一定是可迭代对象,因为它实现了__iter__()方法;
2.通过iter()方法(在类的内部就是__iter__)能够使一个可迭代对象返回一个迭代器。
3.迭代器的 __iter__ 方法返回的是自身,并不产生新的迭代器对象。而可迭代对象的 __iter__ 方法通常会返回一个新的迭代器对象。
第3点性质正是可迭代对象可以重复遍历的原因(每次返回一个独立的迭代器,就可以保证不同的迭代过程不会互相影响);而迭代器由于返回自身,因此只能遍历一次。
上面3点可以通过下面的例子看出来:
from collections import Iterable from collections import Iterator print isinstance(iter([1,2]),Iterator) print isinstance(iter([1,2]),Iterable) print isinstance([1,2],Iterator) print isinstance([1,2],Iterable) ##result True True False True ##id可以查看一个对象在内存中的地址 test=[1,2,3] testIter=iter(test) print id(testIter) print id(testIter) print id(iter(test)) print id(iter(test)) print id(test.__iter__()) print id(test.__iter__()) ##result:可迭代对象每次调用iter方法都会返回一个新的迭代器对象,而迭代器对象调用iter方法返回自身 67162576 67162576 67162688 67162632 67162856 671630242.iterable的工作机制
拿一个例子看看,首先定义一个有__iter__方法,但是没有next()方法的类 (PS:在python2中是next(),python3是__next__()):
from collections import Iterable, Iterator class Student(object): def __init__(self,score): self.score=score def __iter__(self): return iter(self.score) test= Student([80,90,95]) print isinstance(test, Iterable) print isinstance(test, Iterator) for i in test: print i ##result True False 80 90 95 ##可重复遍历 for i in test: print i ##result 80 90 95上面代码的结果印证了定义中提到的:
缺少了next()方法,可迭代对象就不是迭代器。
此外,注意到:可迭代对象通过__iter__方法每次都返回了一个独立的迭代器,这样就可以保证不同的迭代过程不会互相影响。
也就是说,通过iterable可以实现重复遍历,而迭代器是无法重复遍历的!
因此,如果想要把可迭代对象转变为迭代器,可以先调用iter()方法返回一个迭代器。然后就可以用next()不断迭代了!
print isinstance(iter(test),Iterator) testIter=iter(test) print testIter.next() print testIter.next() print testIter.next() ##result True 80 90 95 ##一旦取完了可迭代对象中所有的元素,再次调用next就会发生异常 print testIter.next() ##result StopIteration:3.迭代器Iterator的工作机制
看下面这个例子:
class Student(object): def __init__(self,score): self.score=score def __iter__(self): return self def next(self): if self.score<100: self.score+=1 return self.score else: raise StopIteration() test= Student(90) print isinstance(test, Iterable) print isinstance(test, Iterator) print test.next() print test.next() print test.next() for i in test: print i ##result True True 91 92 93 94 95 96 97 98 99 100 ##如果此时再对test这个迭代器调用next方法,就会抛出异常 test.next() ##result StopIteration:这个例子印证了定义中的:迭代器对象必须同时实现__iter__和__next__方法才是迭代器。
那么,使用迭代器好处在哪呢?
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。