使用迭代器
4.2迭代代表,本节列举了一般在构造迭代器时候,在类里面加入__itrr__()方法
>>> class Node:
... def __init__(self,value):
... self._value=value
... self._children=[]
... def __repr__(self):
... return 'Node({!r})'.format(self._value)
... def add_child(self,node):
... self._children.append(node)
... def __iter__(self):
... return iter(self._children)
可以添加节点之后循环打印出来。
4.3用生成器创造新的迭代模式,使用yield关键字
>>> def frange(start,stop,increment):
... x=start
... while x<stop:
... yield x
... x+=increment
...
>>> for n in frange(0,4,0.5):
... print n,
...
0 0.5 1.0 1.5 2.0 2.5 3.0 3.5
使用next可以依次打印里面的值
>>> c=frange(0,4,1)
>>> next(c)
0
>>> next(c)
1
4.4实现迭代协议,先看这节给出的示例代码,对比4.2多了一个depth_first的函数
class Node:
def __init__(self,value):
self._value=value
self._children=[]
def __repr__(self):
return 'Node({0})'.format(self._value)
def add_child(self,node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
def depth_first(self):
yield self
for c in self:
yield from c.depth_first()
之后执行下面的操作
root=Node(1)
child1=Node(2)
child2=Node(3)
root.add_child(child1)
root.add_child(child2)
child1.add_child(Node(4))
child1.add_child(Node(5))
child2.add_child(Node(6))
最后打印出各节点,本节执行如下操作
for ch in root.depth_first():
print 'hello world'
print(ch)
4.2节执行
for ch in root:
print 'hello world'
print(ch)
对比输出结果,本节Node(1),Node(2),Node(4),Node(5),Node(3),Node(6),上节输出Node(2),Node(3)。下面作者写了一个深度优先的迭代器
>>> class DepthFirstItrrator(object):
... def __init__(self,start_node):
... self._node=start_node
... self._children_iter=None
... self._child_iter=None
... def __iter__(self):
... return self
... def __next__(self):
... if self._children_iter is None:
... self._children_iter=iter(self._node)
... return self._node
... elif self._child_iter:
... try:
... nextchild=next(self._child_iter)
... return nextchild
... except StopIteration:
... self._child_iter=None
... return next(self)
... else:
... self._child_iter=next(self._children_iter).depth_first()
... return next(self)
4.5使用reversed函数可以将一个序列反转。a是一个列表。
>>> for x in reversed(a):
... print x
4.7迭代器是可以切片的,选择其中的一部分,需要import itertools,使用itertools.islice()函数。同时使用这个函数也可跳过部分循环。
4.9使用permutations可以把可能的排列打印出来,使用combinations可以把组合打印出来。
>>> items=[1,2,3]
>>> from itertools import permutations
>>> for p in permutations(items):
... print p
...
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
4.10在迭代中使用enumerate函数,传入一个迭代器和开始的序号,返回序号和每此迭代的内容。
4.11本节我觉得是在使用zip函数
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> list(zip(a,b))
[(1, 4), (2, 5), (3, 6)]
>>> c=[7,8,9,10]
>>> list(zip(b,c))
[(4, 7), (5, 8), (6, 9)]
这里我们可以看见c是多了一位的,但是压缩后还是只有3位,zip默认是按照短的来压缩,若想要把剩余那一位也压缩进去 需要from itertools import zip_longest函数处理。
4.12这节是在介绍itertools里面的chain函数,用于连接序列,比直接使用+更有效率
>>> from itertools import chain
>>> chain(a,b)
<itertools.chain object at 0xb733a96c>
>>> list(chain(a,b))
[1, 2, 3, 4, 5, 6]
4.13