您的位置:首页 > 编程语言 > Python开发

python-cookbook学习笔记九 迭代器与生成器二

2017-05-02 12:01 435 查看
我们来看下yield在类中的应用。代码如下:

class Node:

    def __init__(self,value):

        self._value=value

        self._child=[]

    def __repr__(self):

        return "Node%s" % self._value

    def add_child(self,node):

        self._child.append(node)

    def __iter__(self):

        return iter(self._child)

    def depth_first(self):

        yield self

        for c in self:

            yield c

            for last in c:

                yield last

 

 

def iter_function():

    root=Node(0)

    child1=Node(1)

    child2=Node(2)

    root.add_child(child1)

    root.add_child(child2)

    child1.add_child(Node(3))

    child1.add_child(Node(4))

    child2.add_child(Node(5))

    child2.add_child(Node(6))

    for ch in root.depth_first():

        print ch

在iter_function1中root是根节点。下面有child1和child2 2个子节点。其中child1和child2下面各自有3,4/5,6节点。我们做要实现一个节点的深度遍历。期望得到的结果是Node0,Node1,Node3,Node4,Node2,Node5,Node6.在depth_first中用到了3个yield语句。其中yield self是返回当前的根节点。yield c是返回根节点下的子节点. yield last是继续在上一步的基础上返回上一层的子节点。由于在__iter__中返回的是_child的迭代对象。因此上面的功能也就是不停地遍历各个节点下的_child对象。

执行结果如下:和我们预想的结果一致




我们来看下单步调试的结果:

首先进入Node0节点




打印出Node0



开始遍历Node0的子节点,第一个是Node1



此时ch=Node1



打印出Node1




接着遍历Node1的子节点。第一个是Node3




Ch=Node3



打印出Node3



Node1的下一个子节点Node4





打印出Node4



Node1遍历完后,开始遍历Node2




首先打印出Node2






开始遍历node2,第一个子节点是node5








最后一个是node6








反向遍历列表。有一个列表a=[1,2,3,4].想从列表末尾开始遍历。可以用reversed 来实现这个效果

a=[1,2,3,4]

for x in reversed(a):

    print x

发现迭代只有在对象实现了__reversed__方法且对象大小是确定的情况下才起作用。如果不符合上述条件,必须先将对象转换成列表。

我们可以自定义__reversed__来实现反向迭代。

class CountDown():

    def __init__(self,start):

        self.start=start

    def __iter__(self):

        n=self.start

        while n > 0:

            yield n

            n-=1

    def __reversed__(self):

        n=1

        while n<=self.start:

            yield n

            n+=1

 

for x in CountDown(5):

    print x

print 'reversed result:\n'

for x in reversed(CountDown(5)):

    print x

 

结果如下:




迭代器切片:

假设有如下的代码,count函数实现从n开始的加一操作

def count(n):

    while True:

        yield n

        n+=1

for c in count(5):

    print c

当开始遍历的时候。会一直打印从5开始的加一结果。但是我们只是想得到其中一部分的结果。比如第10到15个生成结果

c=count(<span lang="EN-US" style="" color:"="">5)

print c[10:15]

报如下错误,无法进行数据切片




如果要对生成器进行切片,要用到itertools.islice功能,代码改造如下:

c=count(5)

for x in itertools.islice(c,10,15):

    print x

结果如下,得到了我们想要的结果


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  迭代器 生成器 python