|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
要明白学好linux不是一件一蹴而就的事,一定要能坚持使用它,特别是在使用初期。
【译注】:作为一门静态剧本言语,Python对编程初学者而言很友爱,丰厚的第三方库可以给利用者带来很年夜的便当。而Python同时也可以供应一些初级的特征便利用户利用更加庞大的数据布局。本系列文章共有三篇,本文是系列的第一篇,将会先容迭代器、天生器和itertools模块的相干用法。因为作者SahandSaba枚举的示例中有诸多专业的数学相干内容,因而翻译中有诸多不当的地方请人人指出,十分感激。
对数学家来讲,Python这门言语有着良多吸引他们的中央。举几个例子:关于tuple、lists和sets等容器的撑持,利用与传统数学相似的标记标志体例,另有列表推导式如许与数学中汇合推导式和集的布局式(set-buildernotation)很类似的语法布局。
别的一些很吸引数学喜好者的特征是Python中的iterator(迭代器)、generator(天生器)和相干的itertools包。这些工具匡助人们可以很轻松的写出处置诸如无量序列(infinitesequence)、随机历程(stochasticprocesses)、递推干系(recurrencerelations)和组合布局(combinatorialstructures)等数学对象的文雅代码。本文将涵盖我关于迭代器和天生器的一些条记,而且有一些我在进修过程当中堆集的相干履历。
Iterators
迭代器(Iterator)是一个能够对汇合举行迭代会见的对象。经由过程这类体例不必要将汇合全体载进内存中,也正因云云,这类汇合元素几近能够是无穷的。你能够在Python官方文档的“迭代器范例(IteratorType)”部分找到相干文档。
让我们对界说的形貌再正确些,假如一个对象界说了__iter__办法,而且此办法必要前往一个迭代器,那末这个对象就是可迭代的(iterable)。而迭代器是指完成了__iter__和next(在Python3中为__next__)两个办法的对象,前者前往一个迭代器对象,尔后者前往迭代历程的下一个汇合元素。据我所知,迭代器老是在__iter__办法中复杂的前往本人(self),由于它们恰是本人的迭代器。
一样平常来讲,你应当制止间接挪用__iter__和next办法。而应当利用for或是列表推导式(listcomprehension),如许的话Python可以主动为你挪用这两个办法。假如你必要手动挪用它们,请利用Python的内建函数iter和next,而且把方针迭代器对象或是汇合对象当作参数传送给它们。举个例子,假如c是一个可迭代对象,那末你可使用iter(c)来会见,而不是c.__iter__(),相似的,假如a是一个迭代器对象,那末请利用next(a)而不是a.next()来会见下一个元素。与之相相似的另有len的用法。
说到len,值得注重的是对迭代器而言没需要往纠结length的界说。以是它们一般不会往完成__len__办法。假如你必要盘算容器的长度,那末必需到手动盘算,大概利用sum。本文末,在itertools模块以后会给出一个例子。
有一些可迭代对象并非迭代器,而是利用其他对象作为迭代器。举个例子,list对象是一个可迭代对象,但并非一个迭代器(它完成了__iter__但并未完成next)。经由过程上面的例子你能够看到list是怎样利用迭代器listiterator的。同时价得注重的是list很好地界说了length属性,而listiterator却没有。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>>a=[1,2]
>>>type(a)
<typelist>
>>>type(iter(a))
<typelistiterator>
>>>it=iter(a)
>>>next(it)
1
>>>next(it)
2
>>>next(it)
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
StopIteration
>>>len(a)
2
>>>len(it)
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
TypeError:objectoftypelistiteratorhasnolen()
当迭代停止却仍旧被持续迭代会见时,Python注释器会抛出StopIteration非常。但是,前述中提到迭代器能够迭代一个无量汇合,以是关于这类迭代器就必需由用户卖力确保不会形成无穷轮回的情形,请看上面的例子:
1
2
3
4
5
6
7
8
9
10
classcount_iterator(object):
n=0
def__iter__(self):
returnself
defnext(self):
y=self.n
self.n+=1
returny
上面是例子,注重最初一行试图将一个迭代器对象转为list,这将招致一个无穷轮回,由于这类迭代器对象将不会中断。
1
2
3
4
5
6
7
8
9
10
>>>counter=count_iterator()
>>>next(counter)
0
>>>next(counter)
1
>>>next(counter)
2
>>>next(counter)
3
>>>list(counter)#Thiswillresultinaninfiniteloop!
最初,我们将修正以上的程序:假如一个对象没有__iter__办法但界说了__getitem__办法,那末这个对象仍旧是可迭代的。在这类情形下,当Python的内建函数iter将会前往一个对应此对象的迭代器范例,并利用__getitem__办法遍历list的一切元素。假如StopIteration或IndexError非常被抛出,则迭代中断。让我们看看以下的例子:
1
2
3
4
5
6
classSimpleList(object):
def__init__(self,*items):
self.items=items
def__getitem__(self,i):
returnself.items
用法在此:
1
2
3
4
5
6
7
8
9
10
11
12
>>>a=SimpleList(1,2,3)
>>>it=iter(a)
>>>next(it)
1
>>>next(it)
2
>>>next(it)
3
>>>next(it)
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
StopIteration
如今来看一个更风趣的例子:依据初始前提利用迭代器天生HofstadterQ序列。Hofstadter在他的著作《G |
|