今日目录:
-
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__()) # 9 print(iter_obj.__next__()) # 2 print(iter_obj.__next__()) # 3 print(iter_obj.__next__()) # 4 print(iter_obj.__next__()) # 7 # 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)
六、枚举对象
通过for循环迭代器循环遍历可迭代对象,需要知道迭代的索引
作业:
# 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方法,也可以为可迭代对象提供索引支持 # ls = [4, 3, 7, 5, 9] ls = {1,2,3,4,5,6} def my_enumerate(data): count = 0 for i in data: yield (count, i) count += 1 """ for i, v in my_enumerate(ls): print(i, v) """
# 3.用生成器完成获取阶乘得方法,第一次next得到1的阶乘,第二次next得到2的阶乘,依次类推, # 直接for循环,可以依次得到指定范围内得所有阶乘,eg:factorial(10),可以得到1~10之间的10个阶乘 def my_factorial(num): tag = 1 for i in my_range(1, num+1): tag *= i yield tag factorial_obj = my_factorial(10) for i in factorial_obj: print(i) """ 1 2 6 24 120 720 5040 40320 362880 3628800 """
原文地址:https://www.cnblogs.com/xt12321/p/10651229.html
时间: 2024-10-06 17:11:38