Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型
今日目录:
1.迭代器
2.可迭代对象
3.迭代器对象
4.for循环迭代器
5.生成器
6.枚举对象
一、迭代器:
循环反馈的容器(集合类型)
每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
l = [1, 2, 3]
count = 0
while count<len(l):
print(l[count])
count += 1
1.1 为什么要有迭代器?
字符串、列表、元组可以通过索引的方式迭代取出其中包含的元素
字典、集合、文件等类型,没有索引,只有通过不依赖索引的迭代方式才能取值,即迭代器
二、可迭代对象
2.1 什么是可迭代对象
可迭代对象指的是内置有__iter__()方法的对象,即obj.__iter__()
str,list,tuple,dict,set,range(),file,迭代器对象,enumerate(),生成器都是可迭代对象,即:
[].__iter__()
{}.__iter__()
().__iter__()
{1,2}.__iter__()
......
三、迭代器对象
3.1 什么是迭代器对象
可迭代对象通过调用__iter__()方法得到迭代器对象
迭代器对象可以不依赖索引取值(一次从容器中取出一个值)
迭代器对象都有__next__方法,且通过该方法获取容器中的值,获取规则,从前往后一次一个
3.2 有哪些迭代器对象
文件类型、enumerate()、生成器是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__()
ps:
1.迭代器对象去一个值就少一个值
2.取完了再取会报错 --> 可通过try对异常进行捕获,并处理
3.上一个迭代器对象迭代取值完毕后,就取空了,如果要再取值,要重新生成迭代器对象
4.迭代器对象不能求长度(内部值的个数)
5.迭代器对象一定是可迭代对象,而可迭代对象不一定时迭代器对象
# 迭代器对象
iter_obj = st1.__iter__()
print(iter_obj) # <set_iterator object at 0x0000025B85231CF0> print([1, 2, 3].__iter__()) # <list_iterator object at 0x0000017694B0B860> # 迭代器对象去一个值就少一个值
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
# print(iter_obj.__next__()) # 7 # 异常 StopIteration
# 迭代器无法求长度(内部值的个数)
while True:
try:
val = iter_obj2.__next__()
print(val)
except StopIteration:
break
四、for 循环迭代器
自带异常处理的while循环,自动获取被迭代的对象的迭代器对象
原理:
1.执行in后面对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
2.执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3.重复过程2,直到捕捉到异常,StopIteration,结束循环
迭代器的优缺点:
1.优点
提供一种统一的、不依赖于索引的迭代方式
惰性计算,节省内存
2.缺点
无法获取长度(只有在next完毕才知道到底有几个值)
一次性的,只能往后走,不能往前退
# for 循环迭代器,自带异常处理的while循环,自动获取被迭代的对象的迭代器对象
iter_obj = st1.__iter__()
for item in iter_obj:
print(item)
print('----------------华丽的分割线-----------------------------------------------') for item1 in st1:
# 自动完成for item in st1.__iter__()
# 自动完成异常处理
print(item1)
五、生成器
包含yield关键字的函数就是生成器
def fn():
yield 'good'
该函数名()得到的是生成器对象,且不会执行函数体
生成器的应用案例
当访问的数据资源过大,可以将数据用生成器处理,一次只获取所有内容的一条资源
def g_fn():
print("!!!!!!!!!!!!!!!!!!!!")
yield '第一个' print('@@@@@@@@@@@@@@@@@@@@@')
yield '第二个' print('#####################')
yield '第三个' print('$$$$$$$$$$$$$$$$$$$$$')
yield '第四个' g_obj = g_fn() # 在函数内部执行一次,在遇到下一个yield时停止,且可以拿到yield的返回值
r1 = g_obj.__next__()
print(r1) # 从上一次停止的地方继续往下走,再遇到下一个yield的时候停止,且可以拿到yield的返回值
r2 = g_obj.__next__()
print(r2) r3 = g_obj.__next__()
print(r3)
# 重新定义一个range()生成器 def my_range(min, max, step=1):
# min, max = max, min
tag = min
while True:
if tag >= max:
break
yield tag
tag += step range_obj = my_range(5, 10, 1) for i in range_obj:
print(i)
六、枚举对象
枚举对象:通过enumerate()方法,可以为可迭代对象生成迭代索引,其本身也是一个迭代器对象
作业:
# 1.用生成器完成自定义range方法,可以完成系统range的所有功能
def my_range(min, max= 0, step=1):
if step > 0: # 步长为正的
if max == 0: # 如果最大值为 0 --> my_range(10)
min, max = max, min
tag = min
while True:
if tag >= max:
break
yield tag
tag += step
elif step < 0: # 步长为负的
tag = min
if min > max:
while True:
if tag <= max:
break
yield tag
tag += step
else: # 第三个参数不能是 0
print("第三个参数不能是 0 !")
range_obj1 = my_range(10, 1, -2)
range_obj2 = my_range(10) # --------可以用
range_obj3 = my_range(2, 10) # -----可以用
range_obj4 = my_range(2, 10, 2) # --可以用
"""
for i in range_obj1:
print(i)
"""
# 2.用生成器完成自定义enumerate方法,也可以为可迭代对象提供索引支持
# 不判断,和系统一样,传非迭代对象抛异常
def my_enumerate(iterable, start=0):
for v in iterable:
yield (start, v)
start += 1 # 判断,那么传入b1,b2以外的情况也不抛异常
def my_enumerate(iterable, start=0):
# str, list, tuple, set, dict 五个基础
b1 = isinstance(iterable, (str, list, tuple, set, dict))
# 处理字典的keys,values,items
b2 = type(iterable) in [type({}.keys()), type({}.values()), type({}.items())]
if b1 or b2:
for v in iterable:
yield (start, v)
start += 1
else:
yield '暂不能处理' for v in my_enumerate({'a': 1}.items(), 100):
print(v)
# 3.用生成器完成获取阶乘得方法,第一次next得到1的阶乘,第二次next得到2的阶乘,依次类推,直接for循环,可以依次得到指定范围内得所有阶乘,eg:factorial(10),可以得到1~10之间的10个阶乘
def factorial(num):
pro = 1
for i in range(1, num + 1): # 完成累积
pro *= i
yield pro for v in factorial(5):
print(v)
2019.04.05 添加
迭代器、生成器。可迭代对象 官方定义:
# generator -- 生成器
# 返回一个 generator iterator 的函数。
# 它看起来很像普通函数,不同点在于其包含 yield 表达式以便产生一系列值供给 for-循环使用或是通过 next()
# 函数逐一获取。 # iterable -- 可迭代对象
"""
能够逐一返回其成员项的对象。
可迭代对象的例子包括
所有序列类型(例如 list、str 和 tuple)以及某些非序列类型例如 dict、文件对象 以及定义了 __iter__() 方法
或是实现了 Sequence 语义的 __getitem__() 方法的任意自定义类对象。 iterable -- 可迭代对象
可迭代对象被可用于 for 循环以及许多其他需要一个序列的地方(zip()、map() ...)。
当一个可迭代对象作为参数传给内置函数 iter() 时,它会返回该对象的迭代器。
这种迭代器适用于对值集合的一次性遍历。
在使用可迭代对象时,你通常不需要调用 iter() 或者自己处理迭代器对象。
for 语句会为你自动处理那些操作,创建一个临时的未命名变量用来在循环期间保存迭代器。
参见 iterator、sequence 以及 generator。 iterator -- 迭代器
用来表示一连串数据流的对象。
重复调用迭代器的 __next__() 方法(或将其传给内置函数 next())将逐个返回流中的项。
当没有数据可用时则将引发 StopIteration 异常。
到这时迭代器对象中的数据项已耗尽,继续调用其 __next__() 方法只会再次引发 StopIteration 异常。
迭代器必须具有 __iter__() 方法用来返回该迭代器对象自身,因此迭代器必定也是可迭代对象,可被用于其他可迭代对象适用的大部分场合。
一个显著的例外是那些会多次重复访问迭代项的代码。
容器对象(例如 list)在你每次向其传入 iter() 函数或是在 for 循环中使用它时都会产生一个新的迭代器。
如果在此情况下你尝试用迭代器则会返回在之前迭代过程中被耗尽的同一迭代器对象,使其看起来就像是一个空容器。 迭代器类型介绍:
https://docs.python.org/zh-cn/3.7/library/stdtypes.html#typeiter """
Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型的更多相关文章
- python入门(11)条件判断和循环
python入门(11)条件判断和循环 条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: ag ...
- Python入门篇-匿名函数
Python入门篇-匿名函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.匿名函数概述 1>.什么是匿名函数 匿名,即没有名字 匿名函数,即没有名字的函数 2>. ...
- Python 入门学习 -----变量及基础类型(元组,列表,字典,集合)
Python的变量和数据类型 1 .python的变量是不须要事先定义数据类型的.能够动态的改变 2. Python其中一切皆对象,变量也是一个对象,有自己的属性和方法 我们能够通过 来查看变量的类型 ...
- Python入门-内置函数一
什么是内置函数?就是python给你提供的拿来直接用的函数,比如print,input等等,截止到python版本3.6.2 python一共提供了68个内置函数,他们就是python直接提供给我们的 ...
- 大爽Python入门教程 1-1 简单的数学运算
大爽Python入门公开课教案 点击查看教程总目录 1 使用pycharm建立我们的第一个项目 打开pycharm,点击菜单栏,File->New Project 在Location(项目地址) ...
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- Python 入门基础10 --函数基础3 函数对象、名称空间、装饰器
今日内容 1.函数对象 2.名称空间与作用域 3.函数的嵌套调用与闭包 4.装饰器 一.函数对象 1.1 定义 函数名存放的就是函数地址,所以函数名也就是对象,称之为函数对象 1.2 函数对象的应用 ...
- python基础(11):函数(一)
1. 什么是函数 1.我们到⽬前为⽌,已经可以完成⼀些软件的基础功能了.那么我们来完成这样⼀个功能: 约会: print("拿出⼿机") print("打开陌陌" ...
- Python 入门基础12 --函数基础5 匿名函数、内置函数
今日内容: 1.三元表达式 2.列表.元组生成式 | 字典生成式 3.递归 4.匿名函数 5.内置函数 一.三元表达式 三元运算符:就是 if...else... 语法糖 前提:if 和 else # ...
随机推荐
- PAT甲题题解-1081. Rational Sum (20)-模拟分数计算
模拟计算一些分数的和,结果以带分数的形式输出注意一些细节即可 #include <iostream> #include <cstdio> #include <algori ...
- 2-Nineteenth Scrum Meeting-20151219
任务安排 成员 今日完成 明日任务 闫昊 写完学习进度记录的数据库操作 请假(数据库) 唐彬 和服务器老师交流讨论区后台接口 请假(数据库) 史烨轩 尝试使用downloadmanager对noti ...
- page = new String(request.getQueryString().getBytes("ISO-8859-1"),"GBK");解决前台传后台乱码问题
page = new String(request.getQueryString().getBytes("ISO-8859-1"),"GBK");解决前台传后台 ...
- java实现图像的直方图均衡以及灰度线性变化,灰度拉伸
写了四个方法,分别实现图片的灰度化,直方图均衡,灰度线性变化,灰度拉伸,其中好多地方特别是灰度拉伸这一块觉得自己实现的有问题,请大大们多多指教. import java.awt.Image; impo ...
- [转帖]SAP MES生产执行系统解决方案
一.SAP MES概述: SAP公司成立于1972年,总部位于德国,是全球最大的企业管理和协同化商务解决方案供应商.全球第三大独立软件供应商.目前,在全球有120多个国家的超过86,000多家用户正在 ...
- JVM的自愈能力
在IT行业,碰到问题的第一个反应通常是——“你重启过没”——而这样做可能会适得其反,本文要讲述的就是这样的一个场景. 接下来要介绍的这个应用,它不仅不需要重启,而且毫不夸张地说,它能够自我治愈:刚开始 ...
- 还在手动给css加前缀?no!几种自动处理css前缀的方法简介
原文首发于个人博客:还在手动给css加前缀?no!几种自动处理css前缀的方法简介 我们知道在写css的时候由于要兼容不同厂商浏览器,一些比较新的属性需要给它们添加厂商前缀来兼容.移动端还好,基本只要 ...
- hdu 1151 Air Raid 最小路径覆盖
题意:一个城镇有n个路口,m条路.每条路单向,且路无环.现在派遣伞兵去巡逻所有路口,伞兵只能沿着路走,且每个伞兵经过的路口不重合.求最少派遣的伞兵数量. 建图之后的就转化成邮箱无环图的最小路径覆盖问题 ...
- MT【195】三次函数
(2016年清华大学自主招生暨领军计划试题) 已知$x,y,z\in \mathbf{R}$,满足$x+y+z=1,x^2+y^2+z^2=1$,则下列结论正确的有( ) A.$xyz$的最大值为$0 ...
- NOIP2017逛公园(park)解题报告
park作为今年noipday1最后一道题还是相比前面几道题还是有点难度的 首先你可以思考一下,第一天dp不见了,再看一下这题,有向图,看起来就比较像一个dp,考虑dp方程,首先肯定有一维是到哪个节点 ...