递归

递归: # 函数在调用阶段直接或间接地又调用了自身

应用场景: # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)   -->  l = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, ]]]]]]]]]]]]]

# 循环的写法, 列表嵌套越多层越麻烦
for i in l: # 推导思路
if type(i) is int:
print(i)
else:
for item in i:
if type(item) is int:
print(item)
else:
for j in item:
if type(item) is int:
print(item)
else:
... # 函数体的顶用方式(还有一是前面提到过的pass,推荐还是使用 pass来顶替,比较明目)
# 下方嵌套多级循环,往里面取到更下一层列表中的元素 # 递归的写法,代码体简短,不需要考虑循环次数
def get_num(l):
for i in l:
if type(i) is int:
print(i, end=' - ')
else:
get_num(i) get_num(l)
# 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 -

解决方案(循环取与递归取的对比)

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

递归的两个阶段

  回溯:# 从外向里一层一层递归调用下去,回溯阶段必须要有一个明确的结束条件,每进入下一次递归时,问题的规模都应该有所减少(单纯地重复调用自身是毫无意义的)

  递推: # 递推就是从里向外一层一层结束递归

递归案例:

def index():
print('from index')
login() def login():
print('from login')
index() login()
# ..........................此处省略一大堆报错............................................
# File "E:/PyCharm 2019.1.3/ProjectFile/day010/day012/01 函数递归.py", line 120, in index
# print('from index')
# RecursionError: maximum recursion depth exceeded while calling a Python object # 意思是超出了最大递归限数

从上述案例中可得知 python解释限制了递归的深度(不然就是无限循环下去,直到你的内存溢出,然后。。。emmm)

那么下面我们就来测试一下 python解释器中的递归深度

# 1.暴力测试 --> 997、998左右
count = 0
def index():
global count
print(count)
count += 1
index() index()
# .....此处省略报错
# 997 # 最后打印的数字是 997,意味着 python解释器的递归深度约为997 # 2.getrecursionlimit
import sys
print(sys.getrecursionlimit()) # 不是很精确
#

那么如何修改默认的递归深度呢?

# 修改递归深度限制
import sys
sys.setrecursionlimit(1100)

应用场景2(有序列表中元素的二分法查找)

# 抛去 成员运算 in 可以直接返回元素在不在列表中,下面探究递归运用
# 歧义命名 l_find,
# 这里的 l_find 代表“列表查找”,可能会与下面的往右分割列表查找,往左分割存在歧义
# 所以命名规范里的见名知意也要注意,避免引起歧义
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 默认约定输入的必须是数字(乱输的咱就不考虑在内了)
find_num = int(input("请输入您要查找的数字>>>:").strip()) def l_find(find_num, l):
# print(l) # 可以打印中间步骤
mid_index = len(l) // 2
if not l: # 如果是空列表了,说明该元素不在列表里
return False
# 如果目标元素大于中间元素,那就说明元素在右边
if find_num > l[mid_index]:
# 利用列表的切片知识,将列表切割成一个新的列表,用于递归继续查找
tmp_l = l[mid_index + 1:]
res = l_find(find_num, tmp_l)
elif find_num == l[mid_index]:
# print("get it", find_num)
return True
# 如果目标元素小于中间元素,那就说明元素在左边
else:
tmp_l = l[0:mid_index]
res = l_find(find_num, tmp_l)
return res is_exits = l_find(find_num, l)
if is_exits:
print(f"您所要查找的数字{find_num} 在列表l 中。")
else:
print(f"您所要查找的数字{find_num} 不在列表l 中。")
# 请输入您要查找的数字>>>:9
# 您所要查找的数字9 在列表l 中。

算法: 解决问题的高效率的方法(不仅仅局限于数学运算)

三元表达式

先来看这样一段代码

# 比较两个数的大小
def my_max(x,y):
if x > y:
return x
else:
return y

三元表达式实现: res = x if x > y else y ,短短一行就实现了上面函数的功能

三元表达式固定格式: 值1 if 条件 else 值2 ,如果条件成立,返回 值1 ,不成立返回 值2

常见应用场景:( 在编程的时候请尽量避免使用三元表达式嵌套,想要知道结果要去推算,不够直接 )

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

列表生成式(知识点理解可能有误)

需求: 给列表中的除了 macbook的名字都加个马甲 new_ --> new_tank ,

staff = ['tank', 'nick', 'oscar', 'sean', 'macbook']
# 给列表中的除了 macbook的名字都加个马甲 new_ --> new_tank
# for循环实现
staff = ['tank', 'nick', 'oscar', 'sean', 'macbook']
staff2 = []
for people in staff:
if people != 'macbook':
staff2.append("new_%s" %people)
else:
staff2.append(people)
print(staff2)
# ['new_tank', 'new_nick', 'new_oscar', 'new_sean', 'macbook'] # 列表表达式实现
staff = ['tank', 'nick', 'oscar', 'sean', 'macbook']
print(['new_%s' %name for name in staff if name != "macbook"]) # macbook 不满足条件,所以被滤过了
# ['new_tank', 'new_nick', 'new_oscar', 'new_sean']
# print(['new_' + name for name in staff if name != "macbook"])
# 跟上条语句一样的执行效果,不过python不推荐字符串直接相加的拼接方式,它的效率十分的低!应尽量避免使用! # 三元表达式结合列表表达式实现
staff = ['tank', 'nick', 'oscar', 'sean', 'macbook']
print([f'new_{name}' if name != 'macbook' else name for name in staff])
# ['new_tank', 'new_nick', 'new_oscar', 'new_sean', 'macbook']

代码实现

  可以看到,列表生成式只用了一行就实现了。

列表生成式原理(if后面可以不写)

'''
先for循环依次取出列表里面的元素
然后交由 if 判断, 条件成立才会把元素交给for 前面的代码
如果当前条件不成立, 当前元素直接舍弃
不支持再加else 的情况(for 有 else , if 也有 else 会造成冲突)
'''

字典生成式

需求:将 l1 = ['name', 'age', 'hobby'] , l2 = ['jason', 18, 'DBJ'] 两个列表分别作为键值组成一个字典

l1 = ['name', 'age', 'hobby']
l2 = ['jason', 18, 'DBJ'] # for 循环利用字典特性生成字典
d = {}
for i in range(len(l1)):
d[l1[i]] = l2[i]
print(d)
# {'name': 'jason', 'age': 18, 'hobby': 'DBJ'} # 利用内置函数 zip,将 l1与l2 组合成元组,然后利用内置函数dict强转成字典
d1 = dict(zip(l1, l2))
print(d1, zip(l1, l2))
# {'name': 'jason', 'age': 18, 'hobby': 'DBJ'} <zip object at 0x00000248171F21C8> # d2 将l1 与 l2 中的各元素分别作为键值组成一个新的字典,过滤掉 age 这一个键值 ---> 字典生成式
d2 = {k: v for k, v in zip(l1, l2) if k != 'age'}
print(d1, d2)
# {'name': 'jason', 'age': 18, 'hobby': 'DBJ'} {'name': 'jason', 'hobby': 'DBJ'}

集合生成式也可以同理推导出来(没有元组生成器)

key_set = {i for i in l1 if i != "age"}  # 集合生成式
print(se, type(se))
# {'name', 'hobby'} <class 'set'> tp = (i for i in l1) # 没有元组生成器
print(tp, type(tp))
for i in tp:
print(i)
# <generator object <genexpr> at 0x000001F21D24F0C8> <class 'generator'>
# name
# age
# hobby

生成器表达式的意义: 用来创建其他任何类型的序列,增加代码可读性一定程度上可以更高效

列表生成式与三元表达式结合小案例

hello_list = ['halo', 'hi', 'nice to meet you']

hello_list2 = [f"↑{item}" for item in hello_list if len(item) < 10]
print(hello_list2)
# ['↑halo', '↑hi'] hello_list3 = [f"↑{item}" if len(item) < 10 else item for item in hello_list] # 利用三元表达式实现不同处理
print(hello_list3)
# ['↑halo', '↑hi', 'nice to meet you']

对不同类型元素采取不同处理

匿名函数

匿名函数: 没有名字的函数

特点: 临时存在,调用完立即销毁

关键字: lambda

示例:

print(lambda x, y: x + y)  # lambda x, y: x + y 相当于是定义了一个函数
# <function <lambda> at 0x000001DAC45B2E18>
print((lambda x, y: x + y)(1, 3)) # (lambda x, y: x + y)(1, 3) 相当于是定义并调用了这个函数
# # :左边的相当于函数的形参
# :右边的相当于函数的返回值
# 匿名函数通常不会单独使用,正常情况下是配合内置函数(也可以是自己写的函数)一起使用的

python解释器自带的内置函数

python3.6 中的内置函数

max 求最大值、min 求最小值

# 字典值比较,求出工资最高的那个人的名字
d = {
'egon': 30000,
'swb': 88888888888,
'nick': 3000,
'tank': 1000
}
print(max(d, key=lambda name: d[name]))
# swb
print(min(d, key=lambda name: d[name]))
# tank # key(函数的第二个关键字参数)那里返回什么,他就比较什么,最后返回的还是for 循环到的

map 并行遍历(可接收一个自定义函数)

# map 映射,给列表中的所有元素都 +5
l = [1, 2, 3, 4, 5, 6]
print(list(map(lambda x: x + 5, l))) # 基于for循环
# [6, 7, 8, 9, 10, 11]

zip 并行遍历

# zip 拉链  # 基于for循环
l1 = [1, 2, ]
l2 = ['jason', 'egon', 'tank']
l3 = ['a', 'b', 'c']
print(list(zip(l1, l2, l3)))
# [(1, 'jason', 'a'), (2, 'egon', 'b')]

filter 过滤

# filter 过滤
l = [1, 2, 3, 4, 5, 6]
print(list(filter(lambda x: x != 3, l))) # 基于for循环
# [1, 2, 4, 5, 6]

sorted 排序

# sorted排序
l = ['jason', 'egon', 'nick', 'tank']
print(sorted(l, reverse=True))
# ['tank', 'nick', 'jason', 'egon']

reduce 合并(可指定初值)

from functools import reduce  # 需要导包(感觉就不是内置的了)
l = [1, 2, 3, 4, 5, 6]
print(reduce(lambda x, y: x + y, l, 19)) # 19初始值 第一个参数
#
# 当初始值不存在的情况下 按照下面的规律
# 第一次先获取两个元素 相加
# 之后每次获取一个与上一次相加的结果再相加

python递归-三元表达式-列表生成式-字典生成式-匿名函数-部分内置函数-04的更多相关文章

  1. Python 函数递归-三元表达式-列表生成式-字典生成式-匿名函数-内置函数

    上节课复习: 1. 无参装饰器 def 装饰器名字(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res ...

  2. python之三元表达式、列表推导、生成器表达式、递归、匿名函数、内置函数

    目录 一 三元表达式 二 列表推到 三 生成器表达式 四 递归 五 匿名函数 六 内置函数 一.三元表达式 def max(x,y): return x if x>y else y print( ...

  3. python 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    http://www.cnblogs.com/linhaifeng/articles/7580830.html 三元表达式.列表推导式.生成器表达式.递归.匿名函数.内置函数

  4. python基础知识15---三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    阅读目录 一 三元表达式.列表推导式.生成器表达式 二 递归与二分法 三 匿名函数 四 内置函数 五 阶段性练习 一. 三元表达式.列表推导式.生成器表达式 1 三元表达式 name=input('姓 ...

  5. day 14 三元运算符,列表字典推导式,递归,匿名函数,内置函数(排序,映射,过滤,合并)

    一.三元运算符 就是if.....else..... 语法糖 前提:if和else只有一条语句 #原始版 cmd=input('cmd') if cmd.isdigit(): print('1') e ...

  6. python协程函数、递归、匿名函数与内置函数使用、模块与包

    目录: 协程函数(yield生成器用法二) 面向过程编程 递归 匿名函数与内置函数的使用 模块 包 常用标准模块之re(正则表达式) 一.协程函数(yield生成器用法二) 1.生成器的语句形式 a. ...

  7. Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

    Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: ​ 就是迭代器 生成器产生的方式: ​ 1.生成器函数

  8. Python 入门基础12 --函数基础5 匿名函数、内置函数

    今日内容: 1.三元表达式 2.列表.元组生成式 | 字典生成式 3.递归 4.匿名函数 5.内置函数 一.三元表达式 三元运算符:就是 if...else... 语法糖 前提:if 和 else # ...

  9. day14(1)--递归、匿名函数、内置函数

    一.递归 定义:本质上是回溯和递推 回溯:询问答案的过程 递推:推出答案的过程 前提: 回溯到一个有结果的值开始递推 回溯与递推的条件要有规律 方式: 直接递归:自己调用自己 间接递归:通过别人来调用 ...

随机推荐

  1. Spring之ApplicationContext

    (1)ApplicationContext接口容器 ApplicationContext用于加载Spring的配置文件,在程序中充当“容器”的角色.其实现类有两个.通过Ctrl +T查看: A.配置文 ...

  2. 深入浅出Ajax

    原文(我的GitHub):https://github.com/liangfengbo/frontend-ability/issues/1 学习大纲 理解Ajax的工作原理 Ajax核心-XMLHtt ...

  3. mpvue 开发小程序接口数据统一管理

    mpvue项目里做API与数据分离统一管理 小程序里请求数据接口使用wx:request,因为考虑项目比较大,最好把wx:request封装起来,统一使用管理 utils.js 配置开发环境和线上环境 ...

  4. github 上传更新代码(最简单的方法)

    1.首先你需要一个github账号,还没有的朋友先去注册一个吧! GitHub地址:https://github.com/ 我们使用git需要先安装git工具,这里给出下载地址,下载后一路直接安装即可 ...

  5. AIX/Linux/HP-UX查看CPU/内存/磁盘/存储命令

    1.1    硬件环境验证方式 硬件环境主要包括CPU.内存.磁盘/存储.网络设备(如F5等).系统特有设备(如密押设备等)等,其中网络设备和系统特有设备由网络管理员或项目组提供为准,本节主要关注CP ...

  6. Confluence安装、汉化及jira整合

    今天上午装了一下Confluence,刚开始装的时候成功了,成功后进入数据库配置阶段,本人想把jira和confluence整合一起用,刚开始提示数据库连接问题,后来一直问题提示Connection ...

  7. 最全java多线程总结3——了解阻塞队列和线程安全集合不

      看了前两篇你肯定已经理解了 java 并发编程的低层构建.然而,在实际编程中,应该经可能的远离低层结构,毕竟太底层的东西用起来是比较容易出错的,特别是并发编程,既难以调试,也难以发现问题,我们还是 ...

  8. php函数引用

    //在自定义函数中,前面加一个&符号,是对返回静态变量的引用 function &test(){ static $a; $a += 1; echo $a; return $a; } / ...

  9. Java虚拟机详解(二)------运行时内存结构

    首先通过一张图了解 Java程序的执行流程: 我们编写好的Java源代码程序,通过Java编译器javac编译成Java虚拟机识别的class文件(字节码文件),然后由 JVM 中的类加载器加载编译生 ...

  10. kubernetes实战篇之helm使用技巧

    系列目录 使用压缩包安装chart 我们使用helm package打包的时候,默认会在当前位置生成一个tgz压缩包,然后helm把它复制到到$HOME/.helm/repository目录下,现在还 ...