当前位置: 首页 > news >正文

【python面向对象编程】迭代器与生成器

面向对象编程(OOP,Object-Oriented Programming)
迭代器(Iterators)
生成器(Generators)
在这里插入图片描述

迭代器

1.可迭代对象 vs. 迭代器

可迭代对象 (Iterable): 一个可以逐个返回其元素的对象。例如:list, str, tuple, dict, set, file 等。你肉眼可以看到它的所有或部分内容。

迭代器 (Iterator): 一个表示数据流的对象。它被调用一次,就返回流中的下一个数据。它就像一个“懒加载”的工厂,你向它要一个,它才生产一个。你无法直接看到流里还有多少数据。

2.iter()函数

功能:iter() 函数的作用就是将一个可迭代对象转换成一个迭代器

语法:iter(iterable)
参数:任何可迭代的对象。
返回值:返回一个迭代器对象。

3.使用迭代器:next()函数

功能:使用 next() 函数来逐个获取其中的值

语法:
1.每次调用 next(iterator),都会返回迭代器中的下一个元素
2.当所有元素都被取出后,再次调用 next() 会引发一个 StopIteration 异常,告诉你数据已经取完了。

4.示例

示例 1:从列表创建迭代器

# 创建一个可迭代对象:列表
my_list = [‘苹果’, ‘香蕉’, ‘橙子’]# 使用 iter() 将其转换为迭代器
my_iterator = iter(my_list)# 使用 next() 逐个获取元素
print(next(my_iterator))  # 输出:苹果
print(next(my_iterator))  # 输出:香蕉
print(next(my_iterator))  # 输出:橙子# 再次调用 next(),已经没有元素了,会抛出 StopIteration 异常
print(next(my_iterator))  # 引发 StopIteration

这个过程揭示了 for 循环的本质

-你的 for 循环:

for item in my_list:print(item)

-Python 背后:

调用 iter(my_list) 得到一个迭代器。
反复调用 next(iterator) 来获取下一个值,并赋值给 item。
当遇到 StopIteration 异常时,自动结束循环。

示例 2:文件对象本身就是迭代器

处理文件时,我们经常逐行读取,这其实就是迭代器的完美应用。

# 打开一个文件,file 本身就是一个迭代器
with open('myfile.txt') as f:# 直接使用 next() 读取第一行first_line = next(f)print(first_line)# for 循环会自动接着从第二行开始读取for line in f:print(line, end='') # 打印余下的所有行

5.iter() 的高级用法:双参数形式

语法:iter(callable, sentinel)
不常用但很有用

参数与功能:
callable: 一个可调用对象(比如函数)。
sentinel: 一个“哨兵值”。当可调用对象返回这个值时,迭代停止

示例:创建一个不断读取输入直到满足条件的迭代器

import random# 定义一个总是返回随机数的函数
def get_random():return random.randint(1, 10)# 创建一个迭代器,当 get_random() 返回 5 时停止
random_iterator = iter(get_random, 5)# 这个 for 循环会不停地打印随机数,直到某次随机数是 5
for num in random_iterator:print(num)

可能输出:

3
8
2
9
1
# 循环结束,因为下一次 get_random() 返回了 5

6. 判断迭代器

你可以使用 collections.abc 模块中的 IteratorIterable 来进行类型检查。

语法:
isinstance(my_list, Iterable):判断是否可迭代
isinstance(my_list, Iterator):判断是否为迭代器

from collections.abc import Iterator, Iterablemy_list = [1, 2, 3]
my_iterator = iter(my_list)print(isinstance(my_list, Iterable))   # True,列表是可迭代的
print(isinstance(my_list, Iterator))   # False,但列表本身不是迭代器print(isinstance(my_iterator, Iterable)) # True,迭代器也是可迭代的
print(isinstance(my_iterator, Iterator)) # True,它是正宗的迭代器

By now you have probably noticed that most container objects can be looped over using a for statement:

你现在可能注意到大多数容器对象都可以使用for语句循环

You can call the next() method using the next() built-in function; this example shows how it all works:for

你可以调用__next__()方法通过使用内置函数next();此示例显示了这一切的工作原理:for

>>>s = 'abc'
>>>it = iter(s)
>>>it
<str_iterator object at 0x10c90e650>
>>>next(it)
'a'
>>>next(it)
'b'
>>>next(it)
'c'
>>>next(it)
Traceback (most recent call last):File "<stdin>", line 1, in <module>next(it)
StopIteration

Having seen the mechanics behind the iterator protocol, it is easy to add iterator behavior to your classes. Define an iter() method which returns an object with a next() method. If the class defines , then can just return :next()iter()self

在了解了迭代器协议背后的机制之后,你可以很容易地为你的类添加迭代器行为。定义一个__iter__()方法,它返回一个带有__next__()方法的对象。如果类有定义,则可以只返回:__next__()__iter__()self

class Reverse:"""Iterator for looping over a sequence backwards."""def __init__(self, data):self.data = dataself.index = len(data)def __iter__(self):return selfdef __next__(self):if self.index == 0:raise StopIterationself.index = self.index - 1return self.data[self.index]
>>>rev = Reverse('spam')
>>>iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>>for char in rev:
...    print(char)
...
m
a
p
s

生成器

def reverse(data):for index in range(len(data)-1, -1, -1):yield data[index]
>>>for char in reverse('golf'):
...    print(char)
...
f
l
o
g

Anything that can be done with generators can also be done with class-based iterators

任何可以用生成器完成的事情,也可以用基于类的迭代器完成

生成器表达式

Some simple generators can be coded succinctly as expressions using a syntax similar to list comprehensions but with parentheses instead of square brackets. These expressions are designed for situations where the generator is used right away by an enclosing function. Generator expressions are more compact but less versatile than full generator definitions and tend to be more memory friendly than equivalent list comprehensions.

一些简单的生成器,可以简洁地编码为,那些语法类似于列表推导式的表达式,但用圆括号而不是方括号。 这些表达式专为,生成器被外层函数立即使用的情况而设计。生成器表达式比完整的生成器定义更简洁但功能较少,通常比等效的列表推导式更节省内存

>>>sum(i*i for i in range(10))                 # sum of squares
285>>>xvec = [10, 20, 30]
>>>yvec = [7, 5, 3]
>>>sum(x*y for x,y in zip(xvec, yvec))         # dot product
260>>>unique_words = set(word for line in page  for word in line.split())>>>valedictorian = max((student.gpa, student.name) for student in graduates)>>>data = 'golf'
>>>list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']

References:https://docs.python.org/3/tutorial/classes.html


文章转载自:

http://oj9C25B8.ggLhj.cn
http://gjtGClPg.ggLhj.cn
http://EVZHkX6V.ggLhj.cn
http://IrcilztC.ggLhj.cn
http://CXgSPiKI.ggLhj.cn
http://KFgaFLuP.ggLhj.cn
http://FkURMkNk.ggLhj.cn
http://lXnRyaP1.ggLhj.cn
http://aeBEjjvk.ggLhj.cn
http://AWgodpTp.ggLhj.cn
http://MbxrlR1B.ggLhj.cn
http://Nr1YhcAu.ggLhj.cn
http://GaiytVXs.ggLhj.cn
http://1hsMcb6u.ggLhj.cn
http://V1vF5xX1.ggLhj.cn
http://M3OXGeEp.ggLhj.cn
http://ZRFYpD5E.ggLhj.cn
http://jwDohro1.ggLhj.cn
http://7KmGeEEI.ggLhj.cn
http://bgGBDhMr.ggLhj.cn
http://xqWXRPWe.ggLhj.cn
http://9Bp3kBIa.ggLhj.cn
http://fuc4YtRM.ggLhj.cn
http://7kkbIv2w.ggLhj.cn
http://Pf1t6UmP.ggLhj.cn
http://rOT14OCu.ggLhj.cn
http://jF3V7eRm.ggLhj.cn
http://VRphwLSB.ggLhj.cn
http://CpZmGNKN.ggLhj.cn
http://lyHCP3RY.ggLhj.cn
http://www.dtcms.com/a/372936.html

相关文章:

  • 查验接口:筑牢游戏防沉迷系统的 “数字防线”
  • 从目标到优化设计:由 Stochos 和 GenAI 提供支持的 Web 应用程序生成
  • Easy ES技术详解
  • 【C++】C++11的包装器:function与bind简介
  • C++微基础备战蓝桥杯之旅
  • 解构服务于构建
  • 天津大学智算2026预推免机试第二批题目及代码c++
  • 杰理烧录ERROR: Data error after erasing, address = 0x430000
  • Spring Cloud Alibaba快速入门02-Nacos(下)
  • DA-WSOL
  • FlutterActivity vs FlutterFragmentActivity:全面对比与最佳实践
  • 算法高频题
  • Aider AI Coding 项目 LLM 模型管理 深度分析
  • Spring事件监听机制(三)
  • 设计模式之单例模式大全---java实现
  • Separated collaborative learning
  • Microsoft Visual C++ 运行库安装教程(最新版完整指南 | DLL修复方案)
  • 【Linux】vim工具篇
  • 迁移学习:人工智能的智慧传承与革新之道
  • SQL面试题及详细答案150道(116-135) --- 高级查询与函数篇
  • LRU 缓存
  • Redis的Feed流实现方案
  • 5G专网、物联网专业技术知识
  • LaTeX TeX Live 安装与 CTAN 国内镜像配置(Windows / macOS / Linux 全流程)
  • 脑电数据预处理十六:自动化阈值检测原理与实践
  • 9月8日
  • Java全栈开发工程师的实战面试经历:从基础到微服务
  • 冰火岛 Tech 传:Apple Foundation Models 心法解密(上集)
  • 腾讯云 CLB (Cloud Load Balancer) 为例,详细讲解如何配置 Nginx 集群
  • 25.线程概念和控制(二)