本文主要是介绍Python 生成器常用场景一 取代普通迭代器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在上一篇文章
https://blog.csdn.net/nvd11/article/details/138738472
已经简单介绍了生成器 是 一种特殊的迭代器
而的确, 大部分普通的迭代器是可以被生成器取代的, 以达到简化代码的目的。
使用迭代器的例子
我们找回之前介绍迭代器用到的link list 例子:
https://blog.csdn.net/nvd11/article/details/138736024
里面的link list 保护了3个类
Node 类:
class Node:def __init__(self, value):self._value = valueself._next = None@propertydef value(self):return self._value@propertydef next(self):return self._next@next.setterdef next(self, next):self._next = next@value.setterdef value(self, value):self._value = value
LinkList类 它是iterable 可迭代对象
from loguru import loggerfrom src.iterator.sample_link_list.link_list_iterator import LinkListIterator
from src.iterator.sample_link_list.node import Nodeclass LinkList:def __init__(self, first) -> None:node = Node(first)_first_node = node_last_node = nodedef __init__(self, *values) -> None:if len(values) < 1:raise ValueError("At least one node is required")self._first_node = Node(values[0])current = self._first_nodefor i in range(1, len(values)):current.next = Node(values[i])current = current.nextself._last_node = currentdef __iter__(self):return LinkListIterator(self._first_node)# to print all nodes's value but not nodes themselvesdef print_nodes(self):current = self._first_nodewhile current:logger.info(current.value)current = current.nextdef get_length(self):current = self._first_nodecount = 0while current:count += 1current = current.nextreturn countdef append(self, value):if self.get_length() == 0:self._first_node = Node(value)self._last_node = self._first_nodeelse:self._last_node.next = Node(value)self._last_node = self._last_node.next
可以见到, 它的__iter__ 方法返回1个迭代器对象
LinkListIterator(self._first_node)
所以我们还需要被编写这个迭代器的类代码:
它要实现__next__ 方法
class LinkListIterator:def __init__(self, _first_node) -> None:self._current_node = _first_nodedef __iter__(self):return selfdef __next__(self):if not self._current_node:raise StopIterationcurrent = self._current_nodeself._current_node = current.nextreturn current.value
改成用生成器
一旦我们改用生成器, 则只需要让LinkList 这个interable 的__iter__ 方法变成1个生成器即可
如何让1个方法/函数变成1个生成器, 上一篇文章讲过, 就是使用yield 关键字啊
修改后的代码如下:
def __iter__(self):current = self._first_nodewhile current:yield current.valuecurrent = current.nextreturn
注意这个生成器方法默认是没有参数的
所以它第一元素是 self_first_node
之后yield 当前node 的value出去 , 然后不断让当前元素变成下个原属就好
而这时 原来了的LinkListIterator 就不再需要,大大简化了代码!
这篇关于Python 生成器常用场景一 取代普通迭代器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!