百万年薪python之路 -- 迭代器
3.1 可迭代对象
3.1.1 可迭代对象定义
**在python中,但凡内部含有 _ _ iter_ _方法的对象,都是可迭代对象**。
3.1.2 查看对象内部方法
该对象内部含有什么方法除了看源码还有什么其他的解决方式么?当然有了, 可以通过dir() 去判断一个对象具有什么方法
s1 = 'alex'
print(dir(s1))
dir()会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名。这样我们就可以判断python中的一个对象是不是可迭代对象了:
s1 = 'alex'
i = 100
print('__iter__' in dir(i)) # False
print('__iter__' in dir(s1)) # True
3.1.3 小结:
从专业角度来说:但凡内部含有_ _ iter__方法的对象,都是可迭代对象。
可迭代对象可以通过判断该对象是否有_ _iter__方法来判断。
可迭代对象的优点:
可以直观的查看里面的数据。
可迭代对象的缺点:
1.占用内存。
2.可迭代对象不能迭代取值(除去索引,key以外)。
其实for循环把可迭代对象经过一系列的操作变成了迭代器
3.2 迭代器
3.2.1 迭代器的定义
从专业角度来说:迭代器是这样的对象:实现了无参数的_ next _方法,返回序列中的下一个元素,如果没有元素了,那么抛出StopIteration异常.python中的迭代器还实现了__ iter __方法,因此迭代器也可以迭代。 出自《流畅的python》
**在python中,内部含有_ _ Iter _ 方法并且含有 _ next _ _方法的对象就是迭代器。**
3.2.2 如何判断该对象是否是迭代器
ok,那么我们有了这个定义,我们就可以判断一些对象是不是迭代器或者可迭代对象了了,请判断这些对象:str list tuple dict set range 文件句柄 哪个是迭代器,哪个是可迭代对象:
o1 = 'alex'
o2 = [1, 2, 3]
o3 = (1, 2, 3)
o4 = {'name': '太白','age': 18}
o5 = {1, 2, 3}
f = open('file',encoding='utf-8', mode='w')
print('__iter__' in dir(o1)) # True
print('__iter__' in dir(o2)) # True
print('__iter__' in dir(o3)) # True
print('__iter__' in dir(o4)) # True
print('__iter__' in dir(o5)) # True
print('__iter__' in dir(f)) # True
print('__next__' in dir(o1)) # False
print('__next__' in dir(o2)) # False
print('__next__' in dir(o3)) # False
print('__next__' in dir(o4)) # False
print('__next__' in dir(o5)) # False
print('__next__' in dir(f)) # True
f.close()
通过以上代码可以验证,之前我们学过的这些对象,只有文件句柄是迭代器,剩下的那些数据类型都是可迭代对象。
3.2.3 可迭代对象如何转化成迭代器:
l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__()
# <list_iterator object at 0x000002057FE1A3C8>
# 或
obj = iter(l1)
print(obj)
# <list_iterator object at 0x102cc67f0>
3.2.4 迭代器取值:
可迭代对象是不可以一直迭代取值的(除去用索引,切片以及Key),但是转化成迭代器就可以了,迭代器是利用__next__()进行取值:
l1 = [1, 2, 3,]
obj = l1.__iter__() # 或者 iter(l1)
# print(obj) # <list_iterator object at 0x000002057FE1A3C8>
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__() # StopIteration
print(ret)
# 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,
# 那么就报StopIteration的错误。
3.2.5 while模拟for的内部循环机制:
刚才我们提到了,for循环的循环对象一定要是可迭代对象,但是这不意味着可迭代对象就可以取值,因为for循环的内部机制是:将可迭代对象转换成迭代器,然后利用next进行取值,最后利用异常处理处理StopIteration抛出的异常。
l1 = [1, 2, 3, 4, 5, 6]
# 1 将可迭代对象转化成迭代器
obj = iter(l1)
# 2,利用while循环,next进行取值
while 1:
# 3,利用异常处理终止循环
try:
print(next(obj))
except StopIteration:
break
3.2.6 小结:
从专业角度来说:在python中,内部含有_ iter _ 方法就是可迭代对象
从专业角度来说:在python中,内部含有_ iter _ 方法并且含有_ _ next _方法的对象就是迭代器。
迭代器的优点:
节省内存。 迭代器在内存中相当于只占一个数据的空间:因为每次取值 上一条数据会在内存中释放,加载当前的该条数据。
惰性机制。 next一次,取一个值,绝不会多取值。
有一个迭代器模式可以很好的解释上面这两条:迭代是数据处理的基石。当内存中放不下的太多数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式。
迭代器的缺点:
不能直观的查看里面的数据。
取值时不走回头路,只能一直向下取值。
l1 = [1, 2, 3, 4, 5, 6]
obj = iter(l1) # 等于 obj = l1.__iter__()
for i in range(2):
print(next(obj))
for i in range(2):
print(next(obj))
3.3 可迭代对象与迭代器对比
可迭代对象:
是一个 私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的 这么一个数据集。
应用:当你侧重于 对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
迭代器:
是一个非常节省内存,可以记录取值位置,可以直接通过循环+_ _ next _ _方法取值,但是不直观,操作方法比较单一的数据集。
应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。
最新文章
- Exif
- css2----清除浮动
- HTML5播放器FlowPlayer的极简风格效果
- sqlserver 字符串最后一次的位置,截取字符串
- ADO.NET完整增删改
- 手把手搭建自己的android环境
- 缓存插件 EHCache 对象缓存(Spring)
- C++ builder的文件操作
- jquery ajax请求方式与提示用户正在处理请稍等,等待数据返回时loading的显示
- c++ 接口继承和实现继承
- poj 2186 Popular Cows (强连通分量+缩点)
- string与char* 互相转换以及周边问题
- asp 操作 xml
- 透过源码看看Redis中如何计算QPS
- 在windows上安装wamp时遇到apache无法启动,图标为橙色
- 【jquery隐藏、显示事件and提示callback】【淡入淡出fadeToggle】【滑入滑出slideToggle】【动画animate】【停止动画stop】
- Vue项目兼容IE浏览器
- Box-Muller 与 ziggurat
- EF Code First模型约束
- <;string.h>;的学习
热门文章
- pip安装Mysql-python报错EnvironmentError: mysql_config not found
- [Advanced Python] 14 - ";Generator";: calculating prime
- @Data注解getset不起作用
- 容器技术----------->;Docker
- Flask基础(06)-->;视图常用逻辑
- JS/JQuery 文档加载完成
- (八十四)c#Winform自定义控件-导航菜单(类Office菜单)
- 【MySQL】java.sql.SQLException: The server time zone value
- http post 请求,带参数,带请求头
- 视频作品《springboot基础篇》上线了