博客
关于我
python基础之--迭代器和生成器及异常处理
阅读量:796 次
发布时间:2023-03-07

本文共 4498 字,大约阅读时间需要 14 分钟。

迭代器与生成器及异常处理

一、迭代器

迭代器是一种对象,实现了Python的迭代协议(__iter__()__next__() 方法)。通过迭代器,可以逐个访问容器中的元素。

1.1 迭代器的特点

  • 惰性计算:按需生成数据,节省内存。
  • 实现协议
    • __iter__():返回自身。
    • __next__():返回下一个元素;如果没有更多元素,则抛出 StopIteration 异常。
  • **可迭代对象(Iterable)**与迭代器不同:
    • 可迭代对象实现 __iter__() 方法,返回一个迭代器。
    • 迭代器既实现 __iter__() 又实现 __next__()

1.2 创建迭代器

代码如下(示例):

arr = [1, 2, 3, 4, 5]
iterator = iter(arr)
# 通过多次调用 next() 获取元素
re = next(iterator)
print(re) # 输出: 1
re = next(iterator)
print(re) # 输出: 2
# 迭代器用完后再次调用 next() 会抛出 StopIteration
# try:
# re = next(iterator)
# except StopIteration:
# print("迭代器用完")
12345

1.3 自定义迭代器

代码如下:

class Box:
def __init__(self, width):
self.width = width
def __iter__(self):
return self
def __next__(self):
if self.width > 0:
self.width -= 1
return self.width
else:
raise StopIteration
b1 = Box(6)
for i in b1:
print(i)
6 5 4 3 2 1

1.4 案例

代码如下:

import math
class myData:
def __init__(self, data, batch_size=10):
self.data = data
self.index = -1
self.batch_size = batch_size
def __iter__(self):
return self
def __next__(self):
self.index += 1
if self.index >= math.ceil(len(self.data) / self.batch_size):
raise StopIteration
return self.data[self.index * self.batch_size : self.index * self.batch_size + self.batch_size]
data = myData(
["a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd",
"a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd"],
batch_size=4
)
data_loader = iter(data)
# 获取前几批数据
re = next(data_loader)
print(re) # 输出: ['a', 'b', 'c', 'd']
re = next(data_loader)
print(re) # 输出: ['asd', 'asd', 'asdf', '12as']
re = next(data_loader)
print(re) # 输出: ['asasda', 'b', 'c', 'd']
re = next(data_loader)
print(re) # 输出: ['asd', 'asd', 'asdf', '12as']
re = next(data_loader)
print(re) # 输出: 'asasd'
['a', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasda', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasd']

二、生成器

生成器是一种特殊的迭代器,通过函数定义,用 yield 关键字生成值。生成器可以自动实现迭代协议,无需手动实现 __iter__()__next__() 方法。

2.1 生成器的特点

  • 简洁:比手动实现迭代器更易写。
  • 惰性计算:每次调用 next() 时生成一个值。
  • yield:暂停函数执行并返回值,保留函数的状态。

代码如下:

def fn():
print("111")
yield "10000"
print("222")
yield "20000"
re = fn()
print(1) # 输出: 1
print(next(re), "=============") # 输出: 10000 =============
print(2) # 输出: 2
print(next(re)) # 输出: 20000 =============
print(3) # 输出: 3
11110000 =============2222200003

2.2 生成器表达式

代码如下:

def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield b
a, b = b, a + b
fib_gen = fibonacci(10)
for num in fib_gen:
print(num)
11235813213455

2.3 迭代器与生成器的区别对比

特性 迭代器 生成器
实现 手动实现类方法 使用函数和 yield 定义
代码简洁性 较复杂 简单
状态管理 手动管理 自动保存
惰性计算 支持 支持
示例应用 复杂迭代逻辑 简单数据流生成

三,异常处理

程序可能出错时,后面的代码不执行。为了让程序继续执行,可以使用异常处理语法。异常处理可以让程序在出错后继续执行后面的代码,增强程序的健壮性。

3.1 try 语句

  • 作用:捕获异常,通知程序,恢复正常状态。
  • 说明
    • except 子句可以有 1 个或多个错误类型匹配。
    • else 子句在没有错误发生时执行。
    • finally 子句在任何情况下都执行。

代码如下:

try:
arr = [100, 20]
x = arr[100] # 出错
print(x)
except IndexError:
print("数组越界")
except ValueError:
print("数据类型错误")
else:
print("没有异常")
finally:
print("不管有没有异常,都会执行")
# 输出:
# 数组越界
# 不管有没有异常,都会执行

3.2 raise 语句

  • 作用:主动抛出错误。
  • 示例
def fn():
x = 10
if 5 < x:
print(x)
else:
raise ValueError("x的值不在范围内")
try:
fn()
except ValueError as e:
print(e)
print("后续代码")

3.3 常见错误类型

以下是几种常见的错误类型及其说明:

错误类型 说明
ZeroDivisionError 除法或取模运算中除以零
ValueError 传入无效的参数
AssertionError 断言语句失败
StopIteration 迭代器没有更多值
IndexError 序列中没有对应的索引
IndentationError 缩进错误
OSError 输入/输出操作失败
ImportError 导入模块失败
NameError 未声明/初始化对象
AttributeError 对象没有属性
GeneratorExit 生成器(generator) 被异常退出
TypeError 对类型无效的操作
KeyboardInterrupt 用户中断执行(通常是输入^C)
OverflowError 数值运算超出最大限制
FloatingPointError 浮点计算错误
BaseException 所有异常的基类
SystemExit 解释器请求退出
Exception 常规错误的基类
StandardError 所有内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
EOFError 到达输入末尾(EOF)
EnvironmentError 操作系统错误的基类
WindowsError 系统调用失败
LookupError 无效数据查询的基类
KeyError 映射中没有对应的键
MemoryError 内存溢出错误
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference) 访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError 语法错误
TabError 代码中混合了 tab 和 空格
SystemError 一般解释器系统错误
UnicodeError Unicode 相关错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误

3.4 案例

def get_age():
age = int(input("请输入年龄:"))
if age > 140 or age < 1:
raise ValueError("年龄超出范围!")
else:
print("年龄:", age)
get_age()
ValueError: 年龄超出范围!

转载地址:http://ooofk.baihongyu.com/

你可能感兴趣的文章
python | 深入理解Python并发编程中的GIL限制与解决方案
查看>>
Python | 爬虫实战——亚马逊搜索页监控(附详细源码)
查看>>
python | 高效使用Python工具自动生成模块文档的秘诀
查看>>
python 一个list去除另一个list中的值
查看>>
python 三大框架的 介绍。
查看>>
Python 下载的 11 种姿势,一种比一种高级!
查看>>
python读取一个文件夹下所有图片_初学Python-找出文件夹下的所有图片
查看>>
Python 中 3 个不可思议的返回功能
查看>>
python 中 dict 的另一种用法
查看>>
Python 中 PIL 读取图片出现异常旋转的解决方法
查看>>
python读取word表格内容(1)
查看>>
python 中os.path.join 双斜杠的解决办法
查看>>
python 中PIL.Image和OpenCV图像格式相互转换
查看>>
Python 中Semaphore 信号量对象、Event事件、Condition
查看>>
python 中with的使用及样例
查看>>
python读取txt文件的行数
查看>>
Python 中内置的最大堆 API
查看>>
Python 中只有一个 True 和一个 False 对象吗?
查看>>
python读取mtcars数据集并实现以下操作_关于数据处理。。,Python交流,技术交流区,鱼C论坛 - Powered by Discuz!...
查看>>
Python 中多线程与多处理之间的区别
查看>>