前言
迭代器生成器是Python中处理数据的强大工具,它们不仅简化数据处理流程,还优化内存使用。本博客将带您快速了解迭代器生成器的基本概念、使用方法及其优势,助您提升Python编程效率。让我们一同探索迭代器生成器的魅力!
一、什么是迭代?
日常生活中:迭代是指更新换代
代码开发中:迭代也称之循环、遍历
迭代是访问集合元素的一种方式.
此处的集合不是数据类型集合set,代指一堆数据
二、可迭代对象
1.概念
迭代又称之为循环遍历
.
可迭代对象:
表象:
可以被for循环循环遍历的对象
本质:
底层拥有iter方法的对象.
iter方法:
如果在类中使用,以魔法方法的形式使用 _ iter _
如果在类外使用,以调用方法的形式使用 iter()
2.常见的可迭代对象
# 可迭代对象:iterable # 可迭代对象:可以被for循环循环遍历的对象 # 可迭代对象:字符串、列表、元组、字典、集合 # for 临时变量 in 循环变量: # 代码块 for i in {"name":"张三"}: print(i)
3.判断对象是否是可迭代对象
# 判断对象是否是可迭代对象 # isinstance() # 语法:isinstance(对象,可迭代对象) # 作用:判断对象是否是可迭代对象,如果是则返回Ture,否则返回False print(isinstance(10,Iterable)) print(isinstance(10.6,Iterable)) print(isinstance("hello",Iterable)) print(isinstance(["hello"],Iterable)) print(isinstance(("hello",),Iterable)) print(isinstance({"hello"},Iterable)) print(isinstance({"name":"张三"},Iterable))
4.自定义可迭代对象
from collections.abc import Iterable # 自定义可迭代对象 # 定义类 class MyCls: # 初始化一个空列表 def __init__(self): self.list1 = [] # 定义方法实现往列表中增加数据 def add(self): self.list1.append("张三") self.list1.append("喜羊羊") self.list1.append("玛卡巴卡") self.list1.append("汤姆布利伯") def __iter__(self): pass # 给类实例化一个对象 my = MyCls() my.add() # 判断当前对象是否是可迭代对象 print(isinstance(my,Iterable)) # 通过for循环循环对象 for i in my: print(i)
5.iter()和next()
# iterable 可迭代对象 # iterator 迭代器 # Iteration 迭代器 # iter()函数和next()函数 # iter()函数功能:返回一个迭代器 # iter()函数作用:得到可迭代对象的迭代器 # next()函数功能:编写迭代器要执行的功能 list1 = ["张三","李四","王五"] # iter(可迭代对象) # ret:获取到的当前可迭代对象提供的迭代器 ret = iter(list1) # next(迭代器对象) print(next(ret)) print(next(ret)) print(next(ret)) # 迭代完成再次的迭代抛出停止迭代 StopIteration 的异常 print(next(ret)) # 总结: # 通过`iter()`函数获取可迭代对象的迭代器。 # 对获取到的迭代器不断使用`next()`函数来获取下一条数据
6.for循环底层执行原理
`for item in Iterable` 循环的本质就是先通过`iter()`函数获取可迭代对象`Iterable`的迭代器`Iterator`, 然后对获取到的迭代器`Iterator`不断调用`next()`方法来获取下一个值并将其赋值给`item`, 当遇到`StopIteration`的异常后循环结束。
三、迭代器
1.迭代器原理
编写迭代器:底层拥有iter和next方法 # next()函数功能:编写迭代器要执行的功能 迭代器具体实现的功能: 1.返回可迭代对象中的数据 2.记录当前迭代位置 3.迭代完成再次迭代抛出停止迭代的异常
2.自定义迭代器
from collections.abc import Iterable # 自定义可迭代对象及自定义迭代器 # 可迭代对象概念: # 表象:能够被for循环循环的对象 # 本质:底层拥有iter方法的对象 # iter()方法功能: # 返回一个迭代器 # 编写迭代器: # 底层编写iter和next方法 # next()方法功能: # 实现迭代器的功能 # 迭代器的功能: # 1.返回可迭代对象中的数据 # 2.记录当前迭代位置 # 3.迭代完成再次迭代抛出停止迭代的异常 # 自定义可迭代对象 class MyIter: # 初始化空列表 def __init__(self): self.list1 = [] # 当前迭代位置--》充当下标进行使用 self.current = 0 # 定义方法实现往列表增加数据 def add(self): self.list1.append("张三") self.list1.append("喜羊羊") self.list1.append("小灰灰") self.list1.append("玛卡巴卡") def __iter__(self): # iter()要求返回一个迭代器 # 由于当前自己本身就是一个迭代器,return 自己本身 # self-->方法提供的自己本身 return self def __next__(self): # 判断当前迭代位置是否已经到达可迭代对象最后 # 下标的范围: 0 ~ len()-1 # 判断可以迭代:下标 <= len()-1 if self.current <= len(self.list1) - 1: # 1.返回可迭代对象中的数据--》通过下标获取数据 列表【下标】 data = self.list1[self.current] # 2.记录当前迭代位置 +1 self.current += 1 return data else: # 3.迭代完成再次迭代抛出停止迭代的异常 raise StopIteration # 实例化对象 对象名 = 类名() my = MyIter() my.add() # 判断对象是否是可迭代对象 print(isinstance(my,Iterable)) # 获取可迭代对象中的数据 for i in my: print(i)
3.迭代器优化
from collections.abc import Iterable # 迭代器实现自定义可迭代对象并获取其中的数据 # 编写迭代器要求底层必须要有iter和next # iter()功能:返回一个迭代器 # next()功能:迭代器具体要执行的操作都编写在next方法 # 迭代器功能:1.返回可迭代对象中的数据 2.记录当前迭代位置 3.迭代完成再次迭代抛出停止迭代的异常 class MyList: def __init__(self): # 可迭代对象 self.list1 = ["张三","李四","王五","赵六"] # 当前迭代位置 --》下标 self.current = 0 def __iter__(self): # 由于自己本身就是一个迭代器,返回自己本身 return self def __next__(self): # 迭代器案例:条件判断与当前迭代位置有关 # 如果迭代位置没有到达可迭代对象最后,可以迭代 # 下标范围:0 ~ len()-1 if self.current <= len(self.list1)-1: # 1.返回可迭代对象中的数据 通过下标取值 列表[下标] data = self.list1[self.current] # 2.记录当前迭代位置 +1 self.current += 1 return data else: # 3.迭代完成再次迭代抛出停止迭代的异常 raise StopIteration # 实例化对象 对象名 = 类名() my = MyList() # 判断对象是否是可迭代对象 print(isinstance(my,Iterable)) # 获取可迭代对象中的数据 print(tuple(my))
4.迭代器获取数据的方式
# 获取可迭代对象中的数据-->for循环、list强转、tuple强转 # for i in my: # print(i) # print(list(my)) print(tuple(my))
5.案例:迭代器实现斐波那契
# 迭代器实现斐波那契 # 要获取的斐波那契数量由用户输入 # 斐波那契:1.两个初始值 0 1 2.满足a,b=b,a+b class MyFib: def __init__(self,count): # 可迭代对象-->斐波那契数列 self.a = 0 self.b = 1 # 当前迭代位置--》充当记录当前是第几个斐波那契数 self.current = 1 # 需要的斐波那契数量 self.count = count def __iter__(self): return self def __next__(self): # 如果给到的斐波那契数量没有达到想要的斐波那契数量-->继续迭代 if self.current <= self.count: # 1.返回可迭代对象中的数据--》获取斐波那契数 self.a,self.b = self.b,self.a+self.b # 2.记录当前迭代位置 +1 self.current += 1 return self.a else: # 3.迭代完成再次迭代抛出停止迭代异常 raise StopIteration num = int(input("请输入要获取的斐波那契的数量:")) fib = MyFib(num) print(tuple(fib))
四、生成器
1.概念
生成器就是一个特殊的迭代器
2.创建生成器
2.1 第一种方式
# 创建生成器 generator # 列表推导式-->本质就是通过循环往列表中增加数据 list1 = [i**2 for i in range(1,11) if i % 2 == 0] print(list1) print(type(list1)) # 集合推导式 set1 = {i for i in range(1,11)} print(set1) print(type(set1)) # 生成器创建的第一种方式:将列表推导式[]替换成() gen1 = (i for i in range(1,11)) # gen1得到的就是一个生成器对象 print(gen1) print(type(gen1)) # 获取数据的三种方式:for循环、list强转、tuple强转 for i in gen1: print(i)
2.2 第二种方式
# 创建生成器第二种方式:将函数中return替换成yield # return的作用: 1.将值返回 2.结束函数 # yield的作用: 1.将值返回 2.挂起及唤醒生成器 # 编写一个函数,函数功能实现返回数字1-10 def func(): for i in range(1,11): yield i print("--------") # func()--》生成器对象 for i in func(): print(i)
3.yield关键字
使用了yield关键字的函数不再是函数,而是生成器。(即:使用了yield的函数就是生成器) yield关键字有两点作用: 1.保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起 2.将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return返回值的作用 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)