一、迭代器
-
什么是迭代:迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续
下面都是循环的单纯的重复
while True: print(1)
基于索引的迭代取值
l = ['a', 'b', 'c'] i = 0 while i < len(l): print(l[i]) i += 1
-
什么是迭代器:迭代取值的工具
-
为什么要用迭代器:
优点:
- 提供一种不依赖索引的迭代取值方式
- 更节省内存
缺点:
- 不如按照索引的取值方式灵活
- 取值一次性的,只能往后取,无法预测值的个数
-
如何用迭代器:
可迭代的对象:str、list、tuple、dict、set文件对象
但凡内置有
_iter_
方法的对象都称之为可迭代对象迭代器对象:文件对象
既内置有
_iter_
方法又内置有_next_
方法的对象都称之为迭代器对象调用可迭代对象下
_iter_
方法,会有一个返回值,该返回值就是内置的迭代器对象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} iter_d = iter(d) while True: try: v = iter_d.__next__() print(v) except StopIteration: break print('第二次取值') iter_d = iter(d) while True: try: v = iter_d.__next__() print(v) except StopIteration: break
-
for 循环的底层原理:
-
调用in后面那个值/对象的
_iter_
方法,拿到一个迭代器对象iter_obj -
调用迭代器对象
iter_obj._next_()
将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration -
捕捉异常结束循环
-
二、生成器
- 什么是生成器:生成器就是一种自定义的迭代器
- 如何得到生成器:但凡函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器
def func():
print('first')
yield 1
print('second')
yield 2
print('third')
yield 3
g = func()
# print(g)
res1 = next(g)
print(res1) #打印first和1
res2 = next(g)
print(res2) #打印second和2
res3 = next(g)
print(res3) #打印third和3
总结yield:
-
提供一种自定义迭代器的解决方案
-
yield & return
相同点:都可以返回值,返回值没有类型限制个数限制
不同点:return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值
自定义range:
def my_range(start, stop, step=1):
while start < stop: # 5 < 5
yield start # 3
start += step # start=5
for i in my_range(1,500000,2):
print(i)
三、函数的递归调用与二分法
- 函数的递归调用:在调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用
- 递归必须满足两个条件:
- 每进入下一次递归调用,问题的规模都应该有所减少
- 递归必须有一个明确的结束条件
以下递归只是单纯的重复,没有意义
def func():
print(1)
print(2)
print(3)
func()
func()
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
foo()
递归有两个明确的阶段:
- 回溯
- 递推
示范1:
def age(n):
if n == 1:
return 18
return age(n - 1) + 2
print(age(5))
示范2:
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 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)