博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数递归,算法之二分法,表达式,生成式,匿名函数及常用内置函数
阅读量:4571 次
发布时间:2019-06-08

本文共 4421 字,大约阅读时间需要 14 分钟。

函数递归

  定义:函数在调用阶段直接或间接的又调用自身

  小示例:

# 直接调用自身 def func(n):    print('from func',n)    func(n+1)func(1)
# 间接调用自身 def index():    print('from index')    login()def login():    print('from login')    index()login()

这时的两个小示例都会无限之循环下去,不过python在内部做了优化,最多只能调用到998次左右,查看次数代码:

import sysprint(sys.getrecursionlimit())

 

 

函数的递推分为两个阶段

  1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都应该下降,知道有一个最终的结束条件

  2.递推:一次次往回推导的过程

 

案例一

假如现在有5个人,询问第一个人的年龄,第一个人说:我比第二个人大两岁,第二个人说比第三个人大两岁,依次类推,第五个人说:我今年18岁,写一个递归

推导过程:

age(5) = age(4) + 2

age(4) = age(3) + 2

age(3) = age(2) + 2

age(2) = age(1) + 2

age(1) = 18

如果有第n个人,我们可以推出一个公式:age(n) = age(n-1) + 2      age(1) = 18      # 这时的n是已经说出自己年龄的那个人,所以我们根据n-1可得出上一个人的年龄

def age(n):    if n == 1:  # 必须要有结束条件        return 18    return age(n-1) + 2res = age(5)  #传入参数5print(res)

 

案例二

l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]]

将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)

推导思路:使用for循环打印列表,把列表中的值打印出来

for i in l:    if type(i) is int:        print(i)打印结果1[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]

  按照这个结果来看的话,如果有多少个列表那我们就得做多少次for循环,很显然,这个结果不是我们想得到的

注意:递归函数不要考虑循环的次数,只需要把握结束的条件即可

def get_num(l):    for i in l:        if type(i) is int:            print(i)        else:            get_num(i)l1 = []for i in l1:    print(i)

 

 

算法之二分法

  定义:解决问题的高效率的方法

l = [1,3,5,12,57,89,101,123,146,167,179,189,345]

  现在有一个列表,如何取出345这个值,大家肯定都会想到使用for循环,看345在不在列表l中,如果列表中就几万个值,让你取最后一个值,使用for循环岂不是很浪费资源,每个值都要循环。这时我们可以使用二分法,首先取出列表的总长度,然后除以2,取到中间部分的值,判断中间这个值是否大于或小于要取得这个值,如果大于,那我们则切分列表左边,再使用列表的总长度除以2,以此类推

target_num = 101def get_num(l,target_num):    if not l:        print('不是这个值')        return    # 获取列表中间的索引    print(l)    middle_index = len(l) // 2    # 判断target_num跟middle_index对应的数字的大小    if target_num > l[middle_index]:        # 切取列表右半部分        num_right = l[middle_index + 1:]        # 再递归调用get_num函数        get_num(num_right,target_num)    elif target_num < l[middle_index]:        # 切取列表左半部分        num_left = l[0:middle_index]        # 再递归调用get_num函数        get_num(num_left, target_num)    else:        print('找到了',target_num)get_num(l,target_num)

 

 

三元表达式

有两个值,分别是x和y,求他们两个的最大值

 

def may_max(x,y):    if x > y:        return x    return yres = may_max(30, 20)print(res)

 

  上述的代码,可以求出最大值是30,但是写了很多行代码,在我们可以使用一行代码简洁明了的写出上述代码,这种方式叫做三元表达式

x = 99999y = 9898898res = x if x > y else y   # 三元表达式print(res)
固定公式值1 if 条件 else 值2    条件成立 值1    条件不成立 值2

注意:

  三元表达式的应用场景只推荐只有两种的情况的可能下使用

is_free = input('请输入是否免费(y/n)>>>:')is_free = '免费' if is_free == 'y' else '收费'print(is_free)

 

 

列表生成式

l = ['zhangsan', 'lisi', 'wangwu', 'maliu']

在上述列表每一个名字后面加上_somebody

l1 = []for name in l:    l1.append('%s_somebody'%name)    # l1.append(name + '_somebody')  # 在python不推荐使用+操作print(l1)

使用列表生成式

res = ['%s_somebody' %name for name in l]print(res)

 

看了上面的示例之后,如何取出名字后面带有_somebody的名字呢?

l = ['zhangsan_somebody', 'lisi_somebody', 'wangwu_somebody', 'maliu_somebody', 'xiaohong_ddd']

res = [name for name in l if name.endswith('_somebody')]print(res)

小总结:

列表生成式的应用逻辑

  1.先for循环依次取出列表里面的每一个元素

  2.然后交由if判断  条件成立才会交给for前面的代码

  3.如果条件不成立 当前的元素 直接舍弃

 

 

字典生成式

和字典生成式一样,只是括号改变了

l1 = ['zhangsan','123','read']

d = {i:j for i,j in enumerate(l1) if j != '123'}print(d)
res = {i for i in range(10) if i != 4}print(res)

 

 

匿名函数

  定义:没有名字的函数       特点:临时存在用完就没了    关键字:lambda

求x+y的值,使用函数

def my_sum(x,y):    return x + yres = my_sum(1,2) print(res)

使用匿名函数

res = (lambda x,y:x+y)(1,2)print(res)

小总结:

  1.冒号左边的相当于函数的形参

  2.右边的相当于函数的返回值

  3.匿名函数通常不会单独使用,是配合内置函数一起使用的

 

 

内置函数

  

d = {
'zhangsan':30000, 'lisi':88888, 'wangwu':3000, 'maliu':1000 } 有一个字典,求谁的薪资最高 可能会有人想到使用max求最大值,那么我们来测试一下
res = max(d)print(res)打印结果   #zhangsan

  为什么会打印出张三,而不是lisi呢?因为使用max取求字典的最大值得时候默认比较的是key的最大值,在ascii码表中,z的排序最大,   A-Z排序65-69,a-z排序97-122.所以会打印zhangsan位结果,那么如何去做到比较value的值,打印出姓名为结果呢?

print(max(d,key=lambda name:d[name]))

 

map:映射(基于for循环)

l = [1,2,3,4,5,6]print(list(map(lambda x:x+1,l)))   #每次打印列表中的数字自动+1

zip:拉链(基于for循环)

l1 = [1,2,3]l2 = ['jason','egon','tank']print(list(zip(l1,l2)))   # 两两组合,一一对应,如果了l1的值为1,2,3,4,5,也不会影响到1,2,3,匹配到的值

filter:过滤(基于for循环)

l = [1,2,3,4,5,6]print(list(filter(lambda x:x != 3,l)))  把数字3过滤掉

sorted:排序

l = [1,5,3,2,4,6]print(sorted(l))   # 升序
print(sorted(l, reverse=True))  # 降序

reduce:相当于一个加工厂

from functools import reducel = [1,2,3,4,5,6]print(reduce(lambda x,y:x+y,l))  #打印结果21  #在l后没有传参数的时候,他会把列表中多个元素,根据l前面的规则去整合成一个元素,第一次会一次取两个值,后面会一次取一个值,与上次相加的结果再相加
print(reduce(lambda x,y:x+y,l,9))  #指定参数,会一次从列表中取出一个值相加
 

 

 

 

 

转载于:https://www.cnblogs.com/chengzige/p/11177203.html

你可能感兴趣的文章
有点坎坷,却又有点感动。
查看>>
linux的联网以及语言的更改
查看>>
145-PHP 使用<<<和HTML混编(一)
查看>>
栈的顺序存储结构以及实现
查看>>
【python】-- Socket粘包问题 ,解决粘包的几种方法、socket文件下载,md5值检验
查看>>
2016-09-12
查看>>
CDHD驱动器——ServoStudio配置高创伺服速度模式不转
查看>>
完整版本的停车场管理系统源代码带服务端+手机android客户端
查看>>
【UOJ 92】有向图的强联通分量
查看>>
bzoj 1192
查看>>
Windows10/Servers 2016的TrustedInstaller权限获取(及乱改System后救砖
查看>>
关于mysql转移数据库时没有导出sql脚本的情况下,如何导入数据到新的数据库中...
查看>>
链表逆序
查看>>
[zz]链表倒序
查看>>
简单易用的图像解码库介绍 —— stb_image
查看>>
【漏洞复现】永恒之蓝 ms17-010 漏洞利用 攻击手法
查看>>
HTML标签(二)
查看>>
在weblogic下运行Python脚本
查看>>
短信开发技术总结--协议篇
查看>>
HashMap实现原理分析
查看>>