我的Python之旅第五天---迭代器和生成器
一 迭代器
##1迭代器的特点: (1)节省内存 比如展现一个上亿元素的列表并计算,sum([i*i for i in range(1000000000)]) 内存小的机器肯定要宕机 (2)惰性机制 调用一次__next__方法,执行一次 (3)单向执行,不可逆 既就是迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完后结束。只能往前不能后退 ##2 判断对象是不是可迭代对象 (1)常见的课迭代对象 包含字符串str、列表list、元组tuple、字典dict、集合set、range以及文件句柄 (2)第一种判断方法__iter__ ``` str1="abcdegggg" list1=[1,3,4,5] print('__iter__' in dir(str1)) print('__iter__' in dir(list1)) 结果为: True True ``` (2)第二种判断方法 isinstance('abc',Iterable) ``` str1="abcdegggg" list1=[1,3,4,5] from collections import Iterable print(isinstance(str1,Iterable)) print(isinstance(list1,Iterable)) print(isinstance(123,Iterable)) 结果为: True True False ``` ##3创建迭代器的方法 将可迭代对象转化为迭代器 (1)第一种方法__iter__() ``` str1="abcdegggg" list1=[1,3,4,5] obj_str=str1.__iter__() obj_list=list1.__iter__() print(obj_str) print(obj_list) 结果为:迭代器是Python最强大的功能之一,是访问集合元素的一种方式
迭代器是一种可以记住遍历的位置的对象。
print('iter' in dir(str1))
print('next' in dir(str1))
print('iter' in dir(obj_str))
print('next' in dir(obj_str))
结果为:
True
False
True
True
可以看到,str1虽然是可迭代对象,但是内部不含有__next__方法,所以不是迭代器
(2)isinstance(obj_list,Iterable)
from collections import Iterable
list1=[1,3,4,5]
obj_str=str1.iter()
obj_list=list1.iter()
print(isinstance(list1,Iterable))
print(isinstance(obj_list,Iterable))
print(isinstance(124,Iterable))
结果为:
True
True
False
<h3>二 生成器</h3>
<blockquote background-color:yellow;>
<p>在Python中,使用了yield的函数被称为生成器(generator)。<br>
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,等简单的理解生成器就是一个迭代器。在调用生成器的运行的过程中,每当遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值,并在下一次执行next()方法是从当前暂停的位置继续运行。<br>
调用一个生成器,返回的是一个迭代器对象。
</p>
</blockquote>
##1创建一个简单的生成器
def func1():
print(1111)
yield 1
print(2222)
yield 2
print(3333)
yield 3
print(4444)
gener_obj=func1()
print(gener_obj.next())
print(gener_obj.next())
print(gener_obj.next())
结果为:
1111
1
2222
2
3333
3
上边示例中gener_obj=func1()为生成器对象
__next__() 和 yield 必须一一对应
每调用一次__next__()执行一个yield
如果__next__()多于yield则会报错
##2 生成器小试牛刀
(1)
def cloth():
for i in range(1,1000):
yield '衣服%s'%i
ger_obj=cloth()
for i in range(3):
print(ger_obj.next())
结果为:
衣服1
衣服2
衣服3
(2)接下来再次取值时,它会从上次停的地方继续运行
def cloth():
for i in range(1,1000):
yield '衣服%s'%i
ger_obj=cloth()
for i in range(3):
print(ger_obj.next())
for i in range(5):
print(ger_obj.next())
结果为:
衣服1
衣服2
衣服3
衣服4
衣服5
衣服6
衣服7
衣服8
可以看到,它并不会重复打印1-3
##3 send和next的区别
send 和next 都是对生成器取值
send 会给上一个yield 发送一个值。
send 不能用在第一次取值。
最后一个yield 不能得到值
<h3>三 列表生成试</h3>
列表生成试List Comprehensions,是Python内置的非常简单却强大的可以用了创建list的生成试。
##1为何要使用列表生成试
举个例子,要生成list[1,2,3,4,5,6,7]可以用list(range(1,8)):
list(range(1,8))
[1, 2, 3, 4, 5, 6, 7]
如果要生成[1x1,2x2…..10x10]怎么办,方法一是for循环
for i in range(1,11):
list1.append(i*i)
list1
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
循环太繁琐了,二使用列表生成试一行语句就可以搞定上边的list
[x*x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
##2 列表生成试的一般格式
(1)遍历模式
[变量(加工后的变量) for 变量 in iterable] 遍历模式
如:list = [i for i in range(1,11)]
list = [i for i in range(1,11)]
list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(2)筛选模式
[变量(加工后的变量) for 变量 in iterable if 条件] 筛选模式
如:list2 = [i for i in range(1,31) if i % 3 == 0]
list2 = [i for i in range(1,31) if i % 3 == 0]
list2
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
##3 特点
列表生成试,直观可以看出,但是占内存
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)