Python CookBook 第四章 迭代器和生成器

本文深入探讨了Python中的迭代器和生成器,包括手动访问迭代器元素、实现迭代协议、反向迭代、定义带状态的生成器以及如何使用它们进行序列操作,如合并、排序和扁平化处理。通过实例解析了如何用迭代器替换while循环,以及在不同容器中高效迭代的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

4.1 手动访问迭代器中的元素

4.2委托代理

4.3用生成器创建新的迭代模式

4.4 实现迭代协议

4.5反向迭代

4.6定义带有额外状态的生成器函数

4.7 迭代器的切片和跳过前一部分的元素

4.8迭代所有的组合和排序

4.9 以索引——值对的形式进行迭代

4.10 同时迭代多个序列

4.11 在不同的容器中进行迭代

4.12扁平化处理嵌套的序列

4.13合并多个有序序列,在对整个有序序列进行迭代

4.15 用迭代器代替while循环


4.1 手动访问迭代器中的元素

lis = [1,2,3,4]
#手动访问迭代器,next()函数,捕获StopIteration异常,这是告知迭代结束
for a in lis:
    try:
        while a<5:
            lisit = iter(lis)
            a = next(lisit)
            print(a+1)
    except StopIteration:
        pass
#输出2 将无限循环下去
# 了解next函数的结构
lisit = iter(lis)
print(next(lisit))  #1
print(next(lisit))  #2
print(next(lisit))  #3
print(next(lisit))  #4
print(next(lisit))  # File "E:\vippython\Python CookBook\第四章 迭代器和生成器.py", line 22, in <module>
                    # StopIteration

4.2委托代理

# 我们想让列表、元组或其他可以迭代的对象能够完成迭代操作
#一般是定义一个__iter__()方法,将迭代请求传送给对象内部的容器上
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):  #将迭代请求转发给._children的内部持有对象
        return iter(self._children)

#调用
if __name__ == '__main__':
    root = Node(0)
    child1 = Node(1)
    child2 = Node(2)
    root.add_child(child1)
    root.add_child(child2)
    for ch in root:
        print(ch)
#Node(1)Node(2)

4.3用生成器创建新的迭代模式

# 这一步和我们平时用的没有两样,首先定义一个浮点数的生成器函数
def frange(start,stop,step):
    x = start
    while x<stop:
        yield x   #函数中只要出现了yield 就变成了生成器,需要next()响应才能返回响应的值,只不过for语句能够处理好这些细节
        x += step

for i in frange(0,4,0.5):
    print(i)  #0,0.5,1...

4.4 实现迭代协议

#使用生成器的方式实现以深度优先级返回的迭代器将会是一个极好的选择
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):  #将迭代请求转发给._children的内部持有对象
        return iter(self._children)

    def depth_first(self):  #在原来的类上加深一层函数
        yield self   #首先产出自身
        for c in self:
            yield from c.depth_first()  #迭代子节点,,产生其他元素

if __name__ == '__main__':
    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)))
    child1.add_child((Node(5)))

    for ch in root.depth_first():
        print(ch)
# Node(0)
# Node(1)
# Node(3)
# Node(4)
# Node(5)
# Node(2)

4.5反向迭代

# 使用reversed()函数实现
a = [1,2,3,4]
for i in reversed(a):
    print(i)  #4,3,2,1
#如果迭代对象无法确定大小,使用实现__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 i in reversed(Countdown(5)):
    print(i)   #12345
for i in Countdown(5):
    print(i)  #54321

#当两个都不行时
# 将迭代对象转化为列表,在进行反向迭代
a = 'anything'
for
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值