一、迭代器
1.什么是迭代器
迭代:一个重复的过程,但每次重复都是基于上一次重复的结果而继续
迭代器就是迭代取值的工具
2.为什么要用迭代器
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
优点:
I.其可以提供一种不依赖索引的迭代取值方式
II.更节省内存
缺点:
I.不如按照索引的取值方式灵活
II.其为取值一次性的,只能向后取,无法预测值的个数
可迭代对象:内置有__iter__方法的对象,即obj.__iter__(str\list\tuple\dict\set\文件对象)
迭代器对象:既内置有__iter__方法又内置有__next__方法的对象,即open('a.txt').__iter__(文件对象)
迭代器对象为可迭代对象执行obj.__iter__()得到的结果
调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
3.如何用
dic={'a':1,'b':2,'c':3} iter_dic=dic.__iter__() #得到迭代器对象,迭代器.__iter__()得到的仍然是迭代器本身 iter_d=iter(d) #其相当于d.__iter__ print(iter_dic.__next__()) #《==》next(iter_dic) # 需注意,当next次数超过key次数时,会抛出StopIteration结束标志 while True: try: v=iter_d.__next__() print(v) except StopIteration: break #a b c
dic={'a':1,'b':2,'c':3} for k in dic: print(dic[k]) # 1 2 3
for循环的底层原理
1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
2: 执行iter_obj.__next__()即next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3: 重复过程2,直到捕捉到异常StopIteration,结束循环
二、生成器:一种自定义的迭代器
1.如何得到
函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器
def func(): print('first') yield 1 print('second') yield 2 print('third') yield 3 g=func() print(g) # <generator object func at 0x0000025FB008FE08> res1=next(g) # first print(res1) # 1 res2=next(g) # second print(res2) # 2 res3=next(g) # third print(res3) # 3 next(g) # StopIteration
yield:
1.提供一种自定义迭代器的解决方案
2.yield & return
相同:都可以返回值,返回值没有类型/个数限制
不同:return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值
三、函数的递归调用与二分法
递归
1.递归调用:在调用一个函数的过程又直接或间接地调用该函数本身
递归必须满足两个条件:
I.每进入下一次递归调用,问题的规模都应该有所减少
II.递归必须有一个明确的结束条件‘
递归有两个明确的阶段
I.回溯 :一层一层地递归调用下去
II.递推 :在某一层结束掉递归,然后一层一层返回
2.为何用
在某些情况下,基于递归来使用重复的过程比while循环更简单
3.如何用
一个嵌套很多层的列表,用递归取出所有的值 l = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]] def func1(listl): for item in listl: if type(item) is not list: print(item) else: func1(item) func1(l) #or def get(seq): for item in seq: if type(item) is list: get(item) else: print(item) get(l)
二分法
二分法是算法的一种,算法是如何高效地解决问题的思路
nums = [1, 13, 15, 23, 27, 31, 33, 57, 73, 81, 93, 94, 97, 101] # 从小到大排列的数字列表 def binary_search(find_num,nums): print(nums) if len(nums) == 0: print('not exists') return # 功能 mid_index = len(nums) // 2 if find_num > nums[mid_index]: # in the right nums=nums[mid_index+1:] # 重新运行功能,传入新列表 binary_search(find_num,nums) elif find_num < nums[mid_index]: # in the left nums=nums[:mid_index] # 重新运行功能,传入新列表 binary_search(find_num,nums) else: print('find it') # binary_search(97,nums) binary_search(95,nums)