Python3-Cookbook-Study Notes chap4:迭代器与生成器

1.手动遍历迭代器

# 不使用for循环遍历一个可迭代对象中的所有元素
# 使用 next() 函数并在代码中捕获 StopIteration 异常
# 通常来讲, StopIteration 用来指示迭代的结尾。 然而,如果你手动使用上面演示的 next() 函数的话,你还可以通过返回一个指定值来标记结尾,比如 None

items = [1, 2, 3]
# Get the iterator
it = iter(items) # Invokes items.__iter__()
# Run the iterator
next(it) # Invokes it.__next__()
next(it)
next(it)

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):
        return iter(self._children)

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

3.使用生成器创建新的迭代模式

# 一个函数中需要有一个 yield 语句即可将其转换为一个生成器。 跟普通函数不同的是,生成器只能用于迭代操作。 
def countdown(n):
     print('Starting to count from', n)
     while n > 0:
         yield n
         n -= 1
     print('Done!')


# Create the generator, notice no output appears
c = countdown(3)

# Run to first yield and emit a value
next(c)

# Run to the next yield
next(c)

# Run to next yield
next(c)

# Run to next yield (iteration stops)
next(c)

4.实现迭代器协议

5.反向迭代

# 使用内置的 reversed() 函数
# 在自定义类上实现 __reversed__() 方法来实现反向迭代
class Countdown:
    def __init__(self, start):
        self.start = start

    # Forward iterator
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    # Reverse iterator
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

for rr in reversed(Countdown(30)):
    print(rr)
for rr in Countdown(30):
    print(rr)

6.带有外部状态的生成器函数

from collections import deque

class linehistory:
    def __init__(self, lines, histlen=3):
        self.lines = lines
        self.history = deque(maxlen=histlen)

    def __iter__(self):
        for lineno, line in enumerate(self.lines, 1):
            self.history.append((lineno, line))
            yield line

    def clear(self):
        self.history.clear()

7.迭代器切片 —— 函数 itertools.islice()

8.跳过可迭代对象的开始部分

# 遍历一个可迭代对象,但是它开始的某些元素你并不感兴趣,想跳过它们
# itertools.dropwhile() 函数
# 如果你已经明确知道了要跳过的元素的序号的话,那么可以使用 itertools.islice() 来代替

9.排列组合的迭代

# 迭代遍历一个集合中元素的所有可能的排列或组合
# itertools.permutations() 
# 接受一个集合并产生一个元组序列,每个元组由集合中所有元素的一个可能排列组成

from itertools import permutations
for p in permutations(items):
	print(p)

# itertools.combinations() 
# 得到输入集合中元素的所有的组合

# itertools.combinations_with_replacement()  允许同一个元素被选择多次

10.序列上索引值迭代 —— enumerate() 函数

11.同时迭代多个序列 —— zip() 函数

# 还可以使用 itertools.zip_longest() 函数
from itertools import zip_longest

*12.不同集合上元素的迭代 —— itertools.chain() *

13.创建数据处理管道

14.展开嵌套的序列 —— yield from 语句

15.顺序迭代合并后的排序迭代对象 —— heapq.merge() 函数

16.迭代器代替while无限循环

def reader2(s):
    for chunk in iter(lambda: s.recv(CHUNKSIZE), b''):
        pass
        # process_data(data)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值