CP学习笔记(9) - 迭代
2015-12-19 11:59
375 查看
Python中自定义迭代类型,需要包含自定义的
如果一个对象的
for语句也可以用于列举。
编译器首先会检查
Python官网文档Iterator types一章建议迭代对象的
如何理解Python关键字yield:
当函数被调用时,函数体中的代码是不会运行的,函数仅仅是返回一个生成器对象。这里理解起来可能稍微有点复杂。函数中的代码每次会在for循环中被执行,接下来是最难的一部分:
for第一次调用生成器对象时,代码将会从函数的开始处运行直到遇到yield为止,然后返回此次循环的第一个值,接着循环地执行函数体,返回下一个值,直到没有值返回为止。
一旦函数运行再也没有遇到yield时,生成器就被认为是空的。
Python中还有
__next__方法。
__next__方法能够返回迭代类型的下一项,并在迭代结束时提示编译器:
StopIteration。
# define a new iteration class >>> class LetterIter: """An iterator over letters of the alphabet in ASCII order.""" def __init__(self, start='a', end='e'): self.next_letter = start self.end = end def __next__(self): if self.next_letter == self.end: raise StopIteration letter = self.next_letter self.next_letter = chr(ord(letter)+1) return letter # init a object of defined iteration class >>> letter_iter = LetterIter() >>> letter_iter.__next__() 'a' >>> letter_iter.__next__() 'b' >>> next(letter_iter) 'c' >>> letter_iter.__next__() 'd' >>> letter_iter.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 12, in next StopIteration
如果一个对象的
__iter__方法被调用后能够返回一个迭代对象,那么这个对象就是可迭代(iterable)。
>>> class Letters: def __init__(self, start='a', end='e'): self.start = start self.end = end def __iter__(self): return LetterIter(self.start, self.end) >>> b_to_k = Letters('b', 'k') >>> first_iterator = b_to_k.__iter__() >>> next(first_iterator) 'b' >>> next(first_iterator) 'c' >>> second_iterator = iter(b_to_k) >>> second_iterator.__next__() 'b' >>> first_iterator.__next__() 'd' >>> first_iterator.__next__() 'e' >>> second_iterator.__next__() 'c' >>> second_iterator.__next__() 'd'
for语句也可以用于列举。
for <name> in <expression>: <suite>
编译器首先会检查
<expression>是否是可迭代对象,然后调用
__iter__方法。编译器会反复调用
__next__方法直至遇到
StopIteration。每次调用
__next__方法,编译器都会把得到的值绑定在
<name>上,然后执行
<suite>语句。下面两个示例是等价的。
>>> counts = [1, 2, 3] >>> for item in counts: print(item) 1 2 3
>>> items = counts.__iter__() >>> try: while True: item = items.__next__() print(item) except StopIteration: pass 1 2 3
Python官网文档Iterator types一章建议迭代对象的
__iter__方法最好返回迭代对象本身,这样所有迭代对象都是可迭代的。
__next__方法只能用于列举简单的迭代对象,对于复杂的迭代对象需要用到
generator迭代类型。不同的是,
generator迭代类型不使用
return返回值,而是用
yield语句。
如何理解Python关键字yield:
当函数被调用时,函数体中的代码是不会运行的,函数仅仅是返回一个生成器对象。这里理解起来可能稍微有点复杂。函数中的代码每次会在for循环中被执行,接下来是最难的一部分:
for第一次调用生成器对象时,代码将会从函数的开始处运行直到遇到yield为止,然后返回此次循环的第一个值,接着循环地执行函数体,返回下一个值,直到没有值返回为止。
一旦函数运行再也没有遇到yield时,生成器就被认为是空的。
>>> def letters_generator(): current = 'a' while current <= 'd': yield current current = chr(ord(current)+1) >>> for letter in letters_generator(): print(letter) a b c d >>> letters = letters_generator() >>> type(letters) <class 'generator'> >>> letters.__next__() 'a' >>> letters.__next__() 'b' >>> letters.__next__() 'c' >>> letters.__next__() 'd' >>> letters.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
Python中还有
Streams类可以返回数据序列。
Streams实例是懒惰计算(Lazyily Computed)的。
>>> class Stream: """A lazily computed linked list.""" class empty: def __repr__(self): return 'Stream.empty' empty = empty() def __init__(self, first, compute_rest=lambda: empty): assert callable(compute_rest), 'compute_rest must be callable.' self.first = first self._compute_rest = compute_rest @property def rest(self): """Return the rest of the stream, computing it if necessary.""" if self._compute_rest is not None: self._rest = self._compute_rest() self._compute_rest = None return self._rest def __repr__(self): return 'Stream({0}, <...>)'.format(repr(self.first))
Streams实例返回两项:first 和 rest。每次返回值时只计算first,不计算rest。
>>> r = Link(1, Link(2+3, Link(9))) >>> s = Stream(1, lambda: Stream(2+3, lambda: Stream(9))) >>> r.first 1 >>> s.first 1 >>> r.rest.first 5 >>> s.rest.first 5 >>> r.rest Link(5, Link(9)) >>> s.rest Stream(5, <...>) # rest项为None,并没有被计算出来
相关文章推荐
- UFLDL教程答案(4):Exercise:Softmax Regression
- hdu 4472 Count (递推)
- datatables.js 简单使用--多选框和服务器端分页
- BING算法——思路整理(目标检测算法)
- 摩托罗拉(Motorola) MC2180条码采集器 .NET开发 接入条码组件
- UVa 12108 Extraordinarily Tired Students(特别困的学生)
- Unity中的Serializable
- AIX5.3中将Oracle SGA PIN在内存中的步骤
- 如何使cmd窗口正确显示utf-8编码的文字
- apache2.2 搭载本地中转服务器
- 《linux命令行与shell脚本编程大全》学习笔记(2)
- 二分查找的两种写法
- mysql5.7修改root密码
- 新装ubuntu使用vi时方向键不起作用
- 如何使用pdb调试python程序
- tomcat如何以debug模式启动
- A1.0.2 离线瓦片用ol3显示多功能地图
- Python Tornado 使用经验
- wince的一些对sdk封装成c runtime库的实现
- 图像开运算