迭代器,生成器,函数递归与二分法


1. 什么是迭代器
什么是迭代?
迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续
#下列循环知识单纯的重复
while True:
print(1)

# 基于索引的迭代取值
l=['a','b','c']
i=0

while i < len(l):
print(l[i])
i+=1
什么是迭代器?
迭代取值的工具



2. 为什么要用迭代器
迭代器
优点
1. 提供一种不依赖索引的迭代取值方式
2. 更节省内存
缺点:
1. 不如按照索引的取值方式灵活
2. 取值一次性的,只能往后取,无法预测值的个数

3. 如何用迭代器
可迭代的对象:strlist upledictset文件对象
但凡内置有__iter__方法的对象都称之为可迭代对象

迭代器对象: 文件对象
既内置有__iter__方法又内置有__next__方法的对象都称之为迭代器对象


调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象


s='abcdef'
l=['a','b','c']
d={'k1':111,'k2':222,'k3':333}

iter_d=d.__iter__()
# print(iter_d)

try:
print(iter_d.__next__())
print(iter_d.__next__())
print(iter_d.__next__())
print(iter_d.__next__())
except StopIteration:
print('取值完毕')


d={'k1':111,'k2':222,'k3':333}
d={1,2,3,4,5}
d=[1,2,3,4]

iter_d=d.__iter__()
iter_d=iter(d) #d.__iter__

print(next(iter_d)) #iter_d.__next__()

print(len(d))
print(d.__len__())


print(iter_d.__iter__().__iter__().__iter__() is iter_d)

print(d.__iter__().__next__())
print(d.__iter__().__next__())
print(d.__iter__().__next__())



while True:
try:
v=iter_d.__next__()
print(v)
except StopIteration:
break

print('第二次取值')

iter_d=d.__iter__()
while True:
try:
v=iter_d.__next__()
print(v)
except StopIteration:
break


for k in d:
print(k)

for循环的底层原理:
1. 调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj
2. 调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration
3. 捕捉异常结束循环







生成器就是一种自定义的迭代器

如何得到生成器?
但凡函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器



def func():
print('first')
yield 1
print('second')
yield 2
print('third')
yield 3


g=func()
# print(g)

res1=next(g)
print(res1)

res2=next(g)
print(res2)

res3=next(g)
print(res3)

next(g)

总结yield:
1. 提供一种自定义迭代器的解决方案
2. yield & return
相同点: 都可以返回值,返回值没有类型限制个数限制
不同点: return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值



def my_range(start,stop,step=1):
while start < stop: # 5 < 5
yield start # 3
start+=step #start=5

range(1,5,2) # 1 3
for i in my_range(1,5000000000000000000000000000000000000000000,2): # 1 3
print(i)








1. 函数的递归调用:
在调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用

递归必须满足两个条件:
1. 每进入下一次递归调用,问题的规模都应该有所减少
2. 递归必须有一个明确的结束条件
以下递归只是单纯的重复,没有意义
def func():
print(1)
print(2)
print(3)
func()

func()

def bar():
print('from bar')
foo()

def foo():
print('from foo')
bar()

foo()
递归有两个明确的阶段:
1. 回溯
2. 递推



age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=18

age(n)=age(n-1)+2 # n > 1
age(1)=18 # n = 1

def age(n):
if n == 1:
return 18
return age(n-1)+2

print(age(5))

def age(n):
if n==1:
return 18
return age(n-1)+2
print(age(5))



l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

def func(list1):
for item in list1:
if type(item) is not list:
print(item)
else:
# 如果是列表,应该...
func(item)

func(l)

二分法:
nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]

find_num=203
for num in nums:
if num == find_num:
print('find it')
break
else:
print('not exists')


nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]


def foo(list1,num):
print(list1)
if len(list1) == 0:
print('not exist')
return
new_num=len(list1) // 2
if num > list1[new_num]:
# in the right
foo(list1[new_num + 1:],num)
elif num < list1[new_num]:
# in the left
foo(list1[:new_num],num)
else:
print('find it')

foo(nums,203)


原文地址:https://www.cnblogs.com/huangchaonan/p/10059638.html