Day17 of learning python--递归函数和二分查找法

1.初始递归

递归的定义--在一个函数里再调用这个函数本身,递归:递不断地调用这个本身函数,直到符合某个条件之后不再调用函数本身,再层层向上传递返回值(也就是归)

递归的最大深度--Python默认的最大深度是1000以内。因为每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题。

例如下面代码:

n = 0
def stroy():
    global n
    n += 1
    print(n)
    stroy()
stroy()

但是我们可以通过某个手段可以修改它,修改默认参数

import sys
print(sys.setrecursionlimit(100000))
修改递归最大深度

 2.再谈递归

如果存在某个规律,每个按照这个规律可以得到你想问的内容,则可以构造一个递归函数,比如下面,询问年龄

age(1) = age(2)+2
age(2) = age(3)+2
age(3) = age(4)+2
age(4) = 20

如果我们要求age(1)的年龄,我们的函数怎么写?

def age(n):
    if n == 4:
        return 20
    if n>0 and n<4:
        return age(n+1)+2

print(age(1)

3.二分查找法

如果有这样一个列表,让你从这个有序的列表中l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]找12的位置,即找索引

可以使用列表的l.index(12)来查找,也可以用for循环来找。但是如果不使用index(),这个列表很大的时候,计算机一个一个的去找,消耗太多的内存

二分法就是每次和中间的数值比较

# 利用二分查找法,在有序的列表中找到对应的位置,即索引
def find(l,aim,start=0,end=None):    # 参数end,如果直接使用默认参数end(l)则这个l要先定义,这样没有良好的用户体验感
    #end = len(l) 由于每一次进入函数,都会重复赋值,而这个不变,不能更改end的值。
    end = len(l) if end is None else end   # 所以使用三元运算来赋值,为空则赋l的本身长度,不为空,则使用调用函数传入的参数
    mid_index = (end-start) // 2 + start
    if start <= end and start < len(l):   # 防止找不到值,不管是否小于l的max,还是大于l的max l[18]已经超过该索引值了
        if l[mid_index] < aim:
            return find(l,aim,start=mid_index+1,end=end)
        elif l[mid_index] > aim:
            return find(l,aim,start=start,end=mid_index-1)
        else:
            return mid_index
    else:
        return '找不到该值'

l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
ret = find(l,-2)
print(ret)

4.作业讲解

(1)用map来处理字符串列表,把列表中的每一个元素变成sb,例如;Alex_sb

name = ['alex','amy','physic','system']
def func(item):
    return item+'_sb'
ret = map(func,name) # map(func,iter)执行过程就是循环把iter中的每一个元素当做参数,逐一传递到func()中,创建新的列表
print(dir(ret))
print('__iter__' in dir(ret))    # 判断是否可迭代的
for i in ret:        # 使用for循环把迭代器中的每一元素打印出来
    print(i)
print(list(i))      # 由于i是个全局变量,所有最后赋值的是最后一个,因此把字符串强制转换为列表
print(list(ret)) # 由于ret是个迭代器,全部取值完过后,此时为空,而不像可迭代的for取值一样
# ret = map(lambda item:item+'_sb',name)
# ret = [item+'_sb' for item in name]

注意:filter(func,iter),就是循环把iter的每个元素当作参数传入到func里面,如果返回的是True,则把该参数添加到新的列表中去

# ret = map(lambda dic:{dic['name']:dic['shares']*dic['price']},portfolio)
# ret = filter(lambda dic:True if dic['price']>100 else False,portfolio)
# ret = filter(lambda dic:if dic['price'] >100,portfolio)

(2)随意写一个20行以上的文件,运行程序,先将内容读到内存中,用列表存储,接收用户输入页码,每页5条,仅输出当页的内容

with open('F:\hello.txt',encoding='gbk') as f:
    l = f.readlines()   # 把文件中的每一行读到内存中去
    print(l)          # 打印每一行内容
    print(len(l))     # 判断有多少行

pages,mode = divmod(len(l),5)     # 主要考察了这个函数,求整和余数
page_num = int(input('请输入页码:'))
if mode >0:
    pages = pages + 1      #此处计算的是,当有余数的时候,把其当做新的一页
if page_num > pages or page_num <= 0:
    print('输入有误')
elif page_num == pages and mode != 0:   #输出有余数的内容
    for i in range(mode):
        print(l[(page_num-1)*5 + i].strip())
else:
    for i in range(5):
        print(l[(page_num-1)*5 + i].strip())
posted on 2018-10-16 18:20  smile大豆芽  阅读(158)  评论(0)    收藏  举报