python迭代器和生成器

1.迭代器

1.1 可迭代对象

        可迭代对象指的是 实现了__iter__方法的对象,可以被for循环遍历的容器,比如一个列表,自定义的链表等。使用 iter() 方法获取它的迭代对象(可以理解为链表的指针)

1.2 迭代器

        迭代器是指实现了 __iter__ 和 __next__方法对象,__iter__返回它本身,确保每个单独的节点都是可以被迭代的,满足链表可以从第n个元素开始访问的需求;__next__返回它的下一个节点,如果已经遍历完毕则抛出StopIteration异常。

# 实现了__iter__方法,是一个可迭代对象,可以理解为是一个整的链表,但此时还不能单独访问其中的元素 class Node: def __init__(self, data): self.data = data self.next: Node | None = None def __iter__(self): return NodeIter(self) #是迭代器对象,可以理解为指向链表首元素的指针,通过这个指针遍历所有的链表元素 class NodeIter: def __init__(self, node: Node = None): self.current = node def __iter__(self): return self def __next__(self): if self.current is None: raise StopIteration else: node = self.current self.current = self.current.next return node #返回当前节点的值

1.3 可迭代对象和迭代器的区别

  1. 协议不同:可迭代对象只需实现 __iter__(),迭代器需要实现 __iter__() 和 __next__()
  2. 状态:迭代器有内部状态(当前位置),可迭代对象通常没有
  3. 重用性:可迭代对象可多次遍历(每次获取新迭代器),迭代器遍历一次后耗尽
  4. 包含关系:所有迭代器都是可迭代对象,但并非所有可迭代对象都是迭代器

依旧以链表举例,整个链表是一个可迭代对象,遍历这个对象的时候实际上是通过一个指向链表首元素的指针不断地移动到下一个元素来完成的,这个指针就可以理解为迭代器。

2.生成器

2.1 概念

        生成器是一种特殊的迭代器,它通过 yield 关键字动态的返回值,而非一次性返回所有值,适合用来读取大文件或产生无限序列。生成器内部自动实现了 __iter__和__next__.

当一个函数内部使用了yield关键字时,那么它就是一个生成器函数,此时函数的返回值不再是return后的返回值,而是类似于函数的对象 :

<generator object fibonacci at 0x0000026E4B6D20A0>

以一个生成n个斐波那契的生成器举例:

def fibonacci(limit): """生成斐波那契数列""" a, b = 0, 1 count = 0 while count < limit: yield a a, b = b, a + b count += 1

当执行下面的代码时:

fibo = fibonacci(10) print(fibo) #输出:<generator object fibonacci at 0x0000026E4B6D20A0> print(next(fibo)) #输出0 print(next(fibo)) #输出1 print(next(fibo)) #输出1 print(next(fibo)) #输出2

fibo是一个生成器对象,这个对象可以生成10个斐波那契数,但不是同时生成在内存中,而是一个next()取回一个值,这个特性被称作 "惰性加载" 。执行第一个next()时,返回第一个yield后的值并且暂停函数的执行,等到第二次执行next()时从第一个field后开始继续执行,也就是说,当我在第一个 yield下面抛出异常,函数执行一次 next()并不会报错,因为抛出异常语句并没有执行,第二次执行next()才会报错,比如下面的代码:

def generator1(): print('第一个yield之前的语句块') yield 1 print('第一个yield之后的语句块') print(1 / 0) print('第二个yield之前的语句块') yield 2 print('第二个yield之后的语句块') ge = generator1() #产生了一个生成器对象 print(next(ge)) # 只执行 print(1 / 0) 之前的代码函数就被中断了,所有不会报错 print(next(ge)) # 回到第一个yield之后的代码继续执行,执行到print(1 / 0)语句,报错

如果生成器函数中有return语句,return语句依旧有结束函数运行的作用,return之后的语句不可达,但仍然遵循上面的中断原则,并且return后的值是抛出 StopIteration异常的提示信息:

2.2 yield from

        当我们的生成器的数据是从一个列表中取得并且每次返回一个元素时应该怎么写?

def generator(): user_list = ["zhang","li","wang","qian"] for username in user_list: yield username ge = generator() for i in ge: print(i)

yield from就是简化上面的流程,提升生成器的效率,以上代码可以用下面的代码替代:

def generator(): user_list = ["zhang","li","wang","qian"] yield from user_list ge = generator() for i in ge: print(i)

Read more

Spring Boot 版本怎么选?2/3/4 深度对比 + 迁移避坑指南(含 Java 8→21 适配要点)

Spring Boot 版本怎么选?2/3/4 深度对比 + 迁移避坑指南(含 Java 8→21 适配要点)

深度解析Spring Boot 2、3、4版本差异:从特性迭代到生态演进         作为Java生态中最主流的微服务开发框架,Spring Boot的每一次大版本迭代都牵动着开发者的神经。从2018年Spring Boot 2.0发布带来的性能飞跃,到2022年Spring Boot 3.0开启的Jakarta EE迁移新篇章,再到最新Spring Boot 4.0对云原生与模块化的深度强化,三个大版本的演进不仅是API的增减,更是对Java技术生态发展趋势的精准响应。本文将从基础依赖、核心特性、性能优化、生态适配、迁移实践等维度,全面剖析Spring Boot 2、3、4的核心差异,为开发者的版本选型与迁移升级提供详实参考。 一、版本迭代背景与核心定位差异         Spring Boot的版本迭代始终遵循“兼容演进、紧跟生态”的原则,每个大版本都有明确的核心定位,其发布背景与目标直接决定了特性迭代方向。 1.1 Spring Boot 2.x:

By Ne0inhk
Spring Boot 4.0 + JDK 25 + GraalVM:下一代云原生Java应用架构

Spring Boot 4.0 + JDK 25 + GraalVM:下一代云原生Java应用架构

🧑 博主简介:ZEEKLOG博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可关注公众号 “ 心海云图 ” 微信小程序搜索“历代文学”)总架构师,16年工作经验,精通Java编程,高并发设计,分布式系统架构设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。 🤝商务合作:请搜索或扫码关注微信公众号 “ 心海云图 ” Spring Boot 4.0 + JDK 25 + GraalVM:下一代云原生Java应用架构 摘要 随着云原生架构的快速演进,传统Java应用面临的“启动慢、内存高、体积大”三座大山亟待解决。

By Ne0inhk

零基础学Java(4)

碎碎念:我勒个豆!写了这么多天才发现还有好多基础的知识居然没写!!!算了算了,以后如何需要的话再系统地写一遍吧,现在就想到哪写到哪...... 关于print和printf 可变参数 参考文献可以放 3 篇、5 篇甚至 10 篇,格式统一只需要按顺序罗列;Java 的可变参数也一样,允许方法接收 “任意个数” 的同类型参数,不用提前定义参数个数,代码更灵活简洁。 语法格式 修饰符 返回值类型 方法名(参数类型... 参数名) { // 方法体 } * 关键符号:...(三个点,放在参数类型后、参数名前); * 注意事项:一个方法只能有一个可变参数,且必须放在参数列表的最后一位。 实操案例 public class VarargsDemo { // 可变参数方法:接收任意个数的int类型参数(0个、1个、多个都可以) public static int sum(

By Ne0inhk
又一个项级的 Java Multi Agent 开源项目

又一个项级的 Java Multi Agent 开源项目

你好,我是阿香。 前几天,技术群里的小伙伴一直在安利 Solon AI。起初我还在想,Java 生态里不是已经有 Spring AI 了吗?出于好奇,我抽空深入研究了一波,结果真香了! 这不仅是一个 AI 框架,它更像是为 Java 开发者量身定制的 “智能体指挥部”。今天就来聊聊这个让我眼前一亮的顶级 Java Multi-Agent 开源项目。 什么是 Solon AI? 简单来说,Solon AI 是 Solon 生态中专注 AI 应用开发的轻量级框架。如果说大语言模型(LLM)是 AI 的大脑,那么 Solon AI 就是它的 “神经中枢” 和 “拓扑指挥官”。 它不仅仅提供了多智能体协作的架构,

By Ne0inhk