迭代器、生成器、函数递归与二分法
一、迭代器
1.什么是迭代
迭代就是重复一个过程,但不是单纯的重复,每一次的重复都是基于上次重复的结果。
例如:
l=[1,2,3]
count=0
while True:
if count<len(l):
print(l[count])
count+=1
以上每次迭代的结果都是下一次迭代的初始值。
2.迭代器
2.1 什么是迭代器:
迭代取值的工具
2.2 为什么要用迭代器:
优点:
1.提供一种不依赖索引的迭代取值方式
2.更节省内存空间
缺点:
1.不如索引的取值方式灵活
2.取值一次性,只能往后取,无法预测值的个数
2.3 如何用迭代器:
2.3可迭代的对象:
str、list、tuple、dict、set、file
但凡内置有__iter__方法的都称之为可迭代的对象
2.4迭代器对象:file
既内置有__iter__方法又内置有__next__方法的对象都称之为迭代器对象
调用迭代器对象下__iter__方法,会有一个返回值,返回值就是内置的迭代器对象本身
2.4 for循环底层原理
1.调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj
2.调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到抛出异常StopIteration
3.捕捉异常结束循环
二、生成器
1.什么是生成器
生成器就是一种自定义的迭代器
2.如何得到生成器
但凡函数内出现yield关键字,再调用函数不会立刻执行函数体代码,会得到一个返回值,该返回值就是生成器对象
3.总结yield
1.提供了一种自定义迭代器的解决方案
2.yield&return
相同点:都可以返回值,返回值没有类型限制
不同点:return只能返回一次值,yield却可以让函数暂停在某个位置,返回多次值
比如利用生成器代替range:
def func(start,end,steps):
while start < end:
yield start
start += steps
for i in func(1,5,2):
print(i)
三、函数的递归调用与二分法
1.什么是递归调用
在调用一个函数的过程中又调用该函数本身,称之为递归调用
递归调用必须满足两个条件:
1.每进入下一次递归调用,问题的规模都应该有所减少
2.递归必须有一个明确的条件
递归有两个明确的阶段:
1.回溯
2.递推
例如:
l=[1,[2,[3,[4,[5,[6,[7]]]]]]]
def func(list1):
for item in list1:
if type(item) is not list:
print(item)
else:
func(item)
func(l)
2.二分法
从中间一分为二的方法,当数据量很大适宜采用该方法,但数据需是排好序的。
例如:
二分法类似in的用法:
num=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]
def func(n,num):
if len(num) == 0:
print('no')
return
erfen = len(num) // 2
if n < num[erfen]:
num = num[ :erfen]
func(n,num)
elif n > num[erfen]:
num = num[erfen+1: ]
func(n,num)
else:
print('find')
func(23,num)