Python 生成器常用场景一 取代普通迭代器

在上一篇文章

https://blog.csdn.net/nvd11/article/details/138738472

已经简单介绍了生成器 是 一种特殊的迭代器

而的确, 大部分普通的迭代器是可以被生成器取代的, 以达到简化代码的目的。

使用迭代器的例子

我们找回之前介绍迭代器用到的link list 例子:

https://blog.csdn.net/nvd11/article/details/138736024

里面的link list 保护了3个类

Node 类:
python 复制代码
class Node:
    def __init__(self, value):
        self._value = value
        self._next = None
    
    @property
    def value(self):
        return self._value
    
    @property
    def next(self):
        return self._next
    
    @next.setter
    def next(self, next):
        self._next = next

    @value.setter
    def value(self, value):
        self._value = value
LinkList类 它是iterable 可迭代对象
py 复制代码
from loguru import logger

from src.iterator.sample_link_list.link_list_iterator import LinkListIterator
from src.iterator.sample_link_list.node import Node


class LinkList:
    def __init__(self, first) -> None:
        node = Node(first)
        _first_node = node
        _last_node = node

    def __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_node
        for i in range(1, len(values)):
            current.next = Node(values[i])
            current = current.next
        self._last_node = current

    def __iter__(self):
        return LinkListIterator(self._first_node)

    # to print all nodes's value but not nodes themselves
    def print_nodes(self):
        current = self._first_node
        while current:
            logger.info(current.value)
            current = current.next

    def get_length(self):
        current = self._first_node
        count = 0
        while current:
            count += 1
            current = current.next
        return count

    def append(self, value):
        if self.get_length() == 0:
            self._first_node = Node(value)
            self._last_node = self._first_node
        else:
            self._last_node.next = Node(value)
            self._last_node = self._last_node.next
        

        

可以见到, 它的__iter__ 方法返回1个迭代器对象

LinkListIterator(self._first_node)

所以我们还需要被编写这个迭代器的类代码:

它要实现__next__ 方法

python 复制代码
class LinkListIterator:
    def __init__(self, _first_node) -> None:
        self._current_node = _first_node

    def __iter__(self):
        return self
    
    def __next__(self):
        if not self._current_node:
            raise StopIteration
        current = self._current_node
        self._current_node = current.next
        return current.value

改成用生成器

一旦我们改用生成器, 则只需要让LinkList 这个interable 的__iter__ 方法变成1个生成器即可

如何让1个方法/函数变成1个生成器, 上一篇文章讲过, 就是使用yield 关键字啊

修改后的代码如下:

python 复制代码
    def __iter__(self):
        current = self._first_node
        while current:
            yield current.value
            current = current.next
        return

注意这个生成器方法默认是没有参数的

所以它第一元素是 self_first_node

之后yield 当前node 的value出去 , 然后不断让当前元素变成下个原属就好

而这时 原来了的LinkListIterator 就不再需要,大大简化了代码!

相关推荐
AIFQuant23 分钟前
2026 全球股票/外汇/贵金属行情 API 深度对比:延迟、覆盖、价格与稳定性
python·websocket·ai·金融·mcp
Ray Liang43 分钟前
吐血整理JSON-RPC2.0的原理与应用
python
㳺三才人子1 小时前
簡單的 語音助手
python·ai编程·pip
计算机毕业编程指导师1 小时前
【计算机毕设推荐】Python+Hadoop+Spark共享单车数据可视化分析系统 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·数据挖掘·spark·课程设计
2301_795099741 小时前
golang如何在Gin中自定义验证器_golang Gin自定义验证器实现方法
jvm·数据库·python
计算机毕业编程指导师1 小时前
【计算机毕设】基于Hadoop的共享单车订单数据分析系统+Python+Django全栈开发 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·数据挖掘·spark·django
2301_766283441 小时前
如何在MongoDB GridFS中进行按文件大小(length)范围的查询
jvm·数据库·python
他是龙5511 小时前
71:Python安全 & 反序列化 & PYC反编译 & 格式化字符串安全
开发语言·python·安全
2601_956139422 小时前
文体娱媒品牌全案公司哪家强
大数据·人工智能·python
水木流年追梦2 小时前
【python因果库实战27】逆概率加权模型2
开发语言·python