六.递归与二分法、匿名函数、内置函数

一.递归与二分法

1.1递归调用的定义

递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用
#直接调用本身
def f1():
    print('from f1')
    f1()
f1()

#间接调用本身
def f1():
    print('from f1')
    f2()

def f2():
    print('from f2')
    f1()
f1()

# 调用函数会产生局部的名称空间,占用内存,因为上述这种调用会无需调用本身,python解释器的内存管理机制为了防止其无限制占用内存,对函数的递归调用做了最大的层级限制
四 可以修改递归最大深度

import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000)

def f1(n):
    print('from f1',n)
    f1(n+1)
f1(1)

虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归,而且无限制地递归调用本身是毫无意义的,递归应该分为两个明确的阶段,回溯与递推

1.2 递归调用应该分为两个明确的阶段:递推,回溯 

递归分为两个阶段
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(n)=18            #n=1
def age(n):
    if n == 1:
        return 18
    return age(n-1)+2 #age(4)+2

print(age(5))
总结:
1、递归一定要有一个明确地结束条件
2、没进入下一次递归,问题的规模都应该减少
3、在python中没有尾递归优化

1.3递归取值相关代码

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

def tell(l):
    for item in l:
        if type(item) is not list:
            print(item)
        else:
            tell(item)

tell(items)
递归取值相关代码
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')

1.4二分法

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]:
        print('in the right')
        binary_search(list1[mid_index + 1:], find_num)
    elif find_num < list1[mid_index]:
        print('in the left')
        binary_search(list1[:mid_index], find_num)
    else:
        print('find it')
 
binary_search(nums, 111)
二分法相关代码

二.匿名函数

pass

三.内置函数

pass

posted @ 2018-12-28 20:45  王苗鲁  阅读(83)  评论(0编辑  收藏  举报