一、手动访问迭代器中的元素
要手动访问可迭代对象中的元素,可以使用next()函数。
with open('/etc/passwd') as f:
try:
while True:
line = next(f)
print(line, end='')
except StopIteration:
pass
with open('/etc/passwd') as f:
while True:
line = next(f,None)
if line is None:
break
print(line, end='')
二、委托迭代
Python的迭代协议要求__iter__()返回一个特殊的迭代器对象,由该对象实现的__next__()方法来完成实际的迭代。
如果要做的只是迭代另一个容器中的内容,我们不必担心底层细节是如何工作的,所要做的就是转发迭代请求。
class Node:
def __init__(self,value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_children(self,node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
__iter__()方法只是简单地将迭代请求转发给对象内部持有的_children属性上。
四、实现迭代协议
实现一个迭代器能够以深度优先的模式遍历树的节点
class Node:
def __init__(self,value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_children(self,node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
def depch_first(self):
yield self
for c in self:
for k in c.depch_first():
yield k
root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_children(child1)
root.add_children(child2)
child1.add_children(Node(3))
child1.add_children(Node(4))
child2.add_children(Node(5))
for ch in root.depch_first():
print(ch)
# Node(0) Node(1) Node(3) Node(4) Node(2) Node(5)
五、定义带有额外状态的生成器函数
如果想让生成器将状态暴露给用户,别忘了可以轻易地将其实现为一个类,然后把生成器函数的代码放到__iter__()方法中即可。
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 clean(self):
self.history.clear()
with open('somefile.txt') as f:
lines = Linehistory(f)
for line in lines:
if 'python' in line:
for lineno, hline in lines.history:
print('{}:{}'.format(lineno, hline),end='')
使用这个类,可以将其看做是一个普通的生成器函数,但是,由于它会创建一个类实例,所以可以访问内部属性。
十五、合并多个有序序列、再对整个有序序列进行迭代
heapq.merge() 要求所有的输入序列都是有序的。只是简单地检查每个输入序列中的第一个元素,将最小的那个发送出去。不断重复步骤直至耗尽。
>>> import heapq
>>> a = [1, 4, 7, 10]
>>> b = [2, 5, 6, 11]
>>> for c in heapq.merge(a,b):
... print(c) # 1 2 4 5 6 7 19 11
文件读取写入例子:
import heapq
with open('sorted_file_1','rt') as file1,\
open('sorted_file_2','rt') as file2,\
open('merged_file','wt') as outf:
for line in heapq.merge(file1,file2):
outf.write(line)
十六、用迭代器取代while循环
涉及I/O处理的程序中
CHUNKSIZE = 8192
def reader(s):
while True:
data = s.recv(CHUNKSIZE)
if data == b''
break
process_data(data)
利用iter()来替换:
def reader(s):
for chunk in iter(lambda :s.recv(CHUNKSIZE), b''):
process_data(data)
iter()会创建一个迭代器,然后重复调用用户提供的可调用对象,直到它返回哨兵值为止。
来源:https://www.cnblogs.com/5poi/p/11507905.html