python-迭代器-生成器-函数的递归调用与二分法

一、迭代器

  1. 什么是迭代:迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续

    下面都是循环的单纯的重复

    while True:
        print(1)
    

    基于索引的迭代取值

    l = ['a', 'b', 'c']
    i = 0
    
    while i < len(l):
        print(l[i])
        i += 1
    
  2. 什么是迭代器:迭代取值的工具

  3. 为什么要用迭代器:

    优点:

    1. 提供一种不依赖索引的迭代取值方式
    2. 更节省内存

    缺点:

    1. 不如按照索引的取值方式灵活
    2. 取值一次性的,只能往后取,无法预测值的个数
  4. 如何用迭代器:

    可迭代的对象: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
    
  5. for 循环的底层原理:

    1. 调用in后面那个值/对象的_iter_方法,拿到一个迭代器对象iter_obj

    2. 调用迭代器对象iter_obj._next_()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration

    3. 捕捉异常结束循环

二、生成器

  1. 什么是生成器:生成器就是一种自定义的迭代器
  2. 如何得到生成器:但凡函数内出现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:

  1. 提供一种自定义迭代器的解决方案

  2. 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)

三、函数的递归调用与二分法

  1. 函数的递归调用:在调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用
  2. 递归必须满足两个条件:
    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. 递推

示范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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值