Python-迭代器和生成器
Hereto.
这个作者很懒,什么都没留下…
展开
-
手动遍历迭代器
目录问题解决方案讨论问题你想遍历一个可迭代对象中的所有元素,但是却不想使用 for 循环。解决方案为了手动的遍历可迭代对象,使用 next() 函数并在代码中捕获 StopIteration 异常。比如,下面的例子手动读取一个文件中的所有行:def manual_iter(): with open('/etc/passwd') as f: try: while True: ...原创 2020-01-07 16:14:57 · 116 阅读 · 0 评论 -
代理迭代
目录问题解决方案讨论问题你构建了一个自定义容器对象,里面包含有列表、元组或其他可迭代对象。你想直接在你的这个新容器对象上执行迭代操作。解决方案实际上你只需要定义一个 iter () 方法,将迭代操作代理到容器内部的对象上去。比如:class Node: def __init__(self, value): self._value = value self._children =...原创 2020-01-07 16:18:51 · 123 阅读 · 0 评论 -
使用生成器创建新的迭代模式
目录问题解决方案讨论问题你想实现一个自定义迭代模式,跟普通的内置函数比如 range() , reversed() 不一样。解决方案如果你想实现一种新的迭代模式,使用一个生成器函数来定义它。下面是一个生产某个范围内浮点数的生成器:def frange(start, stop, increment): x = start while x < stop: yield x ...原创 2020-01-07 16:26:06 · 107 阅读 · 0 评论 -
实现迭代器协议
目录问题解决方案讨论问题你想构建一个能支持迭代操作的自定义对象,并希望找到一个能实现迭代协议的简单方法。解决方案目前为止,在一个对象上实现迭代最简单的方式是使用一个生成器函数。在 4.2 小节中,使用 Node 类来表示树形数据结构。你可能想实现一个以深度优先方式遍历树形节点的生成器。下面是代码示例:class Node: def __init__(self, value): ...原创 2020-01-07 16:34:09 · 108 阅读 · 0 评论 -
反向迭代
目录问题解决方案讨论问题你想反方向迭代一个序列解决方案使用内置的 reversed() 函数,比如:>>> a = [1, 2, 3, 4]>>> for x in reversed(a):... print(x)...4321反向迭代仅仅当对象的大小可预先确定或者对象实现了 reversed () 的特殊方法时才能生效。如果两者...原创 2020-01-07 16:38:47 · 362 阅读 · 0 评论 -
带有外部状态的生成器函数
目录问题解决方案讨论问题你想定义一个生成器函数,但是它会调用某个你想暴露给用户使用的外部状态值。解决方案如果你想让你的生成器暴露外部状态给用户,别忘了你可以简单的将它实现为一个类,然后把生成器函数放到 iter () 方法中过去。比如:from collections import dequeclass linehistory: def __init__(self, lines, ...原创 2020-01-07 16:41:16 · 107 阅读 · 0 评论 -
迭代器切片
目录问题解决方案讨论问题你想得到一个由迭代器生成的切片对象,但是标准切片操作并不能做到。解决方案函数 itertools.islice() 正好适用于在迭代器和生成器上做切片操作。比如:>>> def count(n):... while True:... yield n... n += 1...>>> c = count(0)>&g...原创 2020-01-07 16:44:09 · 105 阅读 · 0 评论 -
跳过可迭代对象的开始部分
目录问题解决方案讨论问题你想遍历一个可迭代对象,但是它开始的某些元素你并不感兴趣,想跳过它们。解决方案itertools 模 块 中 有 一 些 函 数 可 以 完 成 这 个 任 务。 首 先 介 绍 的 是itertools.dropwhile() 函数。使用时,你给它传递一个函数对象和一个可迭代对象。它会返回一个迭代器对象,丢弃原有序列中直到函数返回 True 之前的所有元素,...原创 2020-01-07 16:47:02 · 112 阅读 · 0 评论 -
排列组合的迭代
目录问题解决方案讨论问题你想迭代遍历一个集合中元素的所有可能的排列或组合解决方案itertools 模 块 提 供 了 三 个 函 数 来 解 决 这 类 问 题。 其 中 一 个 是itertools.permutations() ,它接受一个集合并产生一个元组序列,每个元组由集合中所有元素的一个可能排列组成。也就是说通过打乱集合中元素排列顺序生成一个元组,比如:>>...原创 2020-01-07 16:50:44 · 421 阅读 · 0 评论 -
序列上索引值迭代
目录问题解决方案讨论问题你想在迭代一个序列的同时跟踪正在被处理的元素索引。解决方案内置的 enumerate() 函数可以很好的解决这个问题:>>> my_list = ['a', 'b', 'c']>>> for idx, val in enumerate(my_list):... print(idx, val)...0 a1 b2 c...原创 2020-01-07 16:54:17 · 186 阅读 · 0 评论 -
同时迭代多个序列
目录问题解决方案讨论问题你想同时迭代多个序列,每次分别从一个序列中取一个元素。解决方案为了同时迭代多个序列,使用 zip() 函数。比如:>>> xpts = [1, 5, 4, 2, 10, 7]>>> ypts = [101, 78, 37, 15, 62, 99]>>> for x, y in zip(xpts, ypts)...原创 2020-01-07 16:56:42 · 210 阅读 · 0 评论 -
不同集合上元素的迭代
目录问题解决方案讨论问题你想在多个对象执行相同的操作,但是这些对象在不同的容器中,你希望代码在不失可读性的情况下避免写重复的循环。解决方案itertools.chain() 方法可以用来简化这个任务。它接受一个可迭代对象列表作为输入,并返回一个迭代器,有效的屏蔽掉在多个容器中迭代细节。为了演示清楚,考虑下面这个例子:>>> from itertools import...原创 2020-01-07 17:00:20 · 98 阅读 · 0 评论 -
创建数据处理管道
目录问题解决方案讨论问题你想以数据管道 (类似 Unix 管道) 的方式迭代处理数据。比如,你有个大量的数据需要处理,但是不能将它们一次性放入内存中。解决方案生成器函数是一个实现管道机制的好办法。为了演示,假定你要处理一个非常大的日志文件目录:foo/ access-log-012007.gz access-log-022007.gz access-log-032007.gz ....原创 2020-01-07 17:05:08 · 209 阅读 · 0 评论 -
展开嵌套的序列
目录问题解决方案讨论问题你想将一个多层嵌套的序列展开成一个单层列表解决方案可以写一个包含 yield from 语句的递归生成器来轻松解决这个问题。比如:from collections import Iterabledef flatten(items, ignore_types=(str, bytes)): for x in items: if isinstance(x, I...原创 2020-01-07 17:08:02 · 509 阅读 · 0 评论 -
顺序迭代合并后的排序迭代对象
目录问题解决方案讨论问题你有一系列排序序列,想将它们合并后得到一个排序序列并在上面迭代遍历。解决方案heapq.merge() 函数可以帮你解决这个问题。比如:>>> import heapq>>> a = [1, 4, 7, 10]>>> b = [2, 5, 6, 11]>>> for c in heapq...原创 2020-01-07 17:09:30 · 146 阅读 · 0 评论 -
迭代器代替 while 无限循环
目录问题解决方案讨论问题你在代码中使用 while 循环来迭代处理数据,因为它需要调用某个函数或者和一般迭代模式不同的测试条件。能不能用迭代器来重写这个循环呢?解决方案一个常见的 IO 操作程序可能会想下面这样:CHUNKSIZE = 8192def reader(s): while True: data = s.recv(CHUNKSIZE) if data == b''...原创 2020-01-07 17:11:12 · 874 阅读 · 0 评论