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

我们来看下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_function1root是根节点。下面有child1child2 2个子节点。其中child1child2下面各自有3,4/5,6节点。我们做要实现一个节点的深度遍历。期望得到的结果是Node0,Node1,Node3,Node4,Node2,Node5,Node6.depth_first中用到了3yield语句。其中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开始的加一结果。但是我们只是想得到其中一部分的结果。比如第1015个生成结果
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
结果如下,得到了我们想要的结果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿与代码

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值