Python学习Day14
一、迭代器 1.什么是迭代器 什么是迭代? 迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续 下列循环只是单纯的重复 while True: print(l) 基于索引的迭代取值 l=['a','b','c'] i=0 while i < len(l): print(l[i]) i+=1 什么是迭代器? 迭代取值的工具 2.为什么要用迭代器 迭代器 优点 1.提供一种不依赖索引的迭代取值方式 2.更节省内存 缺点: 1.不如按照索引的取值方式灵活 2.取值一次性的,只能往后取,无法预测值的个数 3.如何用迭代器 可迭代的对象:str\list\tuple\dict\set\文件对象 但凡内置有__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,500000000000000000000,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)) 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') 2.二分法 nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341] def binary_search(list1,find_num): print(list1) if len(list1) == 0: print('not exist') return mid_index=len(list1) // 2 if find_num > list1[mid_index]: # in the right binary_search(list1[mid_index + 1:],find_num) elif find_num < list1[mid_index]: # in the left binary_search(list1[:mid_index],find_num) else: print('find it') binary_search(nums,203)