Day 020 re模块补充 递归函数 带参数的装饰器
01 今日内容大纲
- re模块结尾
- re模块的拾遗
- 带参数装饰器
- 递归函数
02 昨日内容回顾
-
正则表达式
-
元字符
- \d \w \s \t \n \D \W \S
- . [] [^] ^ $
- | ()
-
量词
-
# ? + * #{n} {n,} {n,m}
-
-
贪婪与非贪婪(惰性)
- 默认贪婪
- 量词?
-
转义符
-
如果有特殊意义 \元字符能够取消这个元字符的特殊意义
-
表示只匹配 \后面原本的内容
-
# [. * ? ()]
-
-
-
re模块
- findall
- 会优先显示分组的内容
- 取消优先显示(?:正则)
- search
- 只能返回第一个符合条件的项
- 得到的结果需要 .group() 取值
- 默认获取完整的匹配结果
- 通过group(n)取第n个分组中的内容
- findall
03 今日内容
- re模块结尾
- findall
- search
# findall,search可以解决工作中80%的问题 会遗留下一些效率与空间的问题
-
split
import re # split 以输入元素进行分割 ret = re.split('\d+','alex222wusir') print(ret) #['alex', 'wusir'] ret = re.split('\d(\d)\d','alex222wusir') print(ret) #['alex', '2', 'wusir']
-
sub
import re # sub 替换 ret = re.sub('\d+','H','alex123wusir456') print(ret) #alexHwusirH ret = re.sub('\d+','H','alex123wusir456',1) print(ret) #alexHwusir456
-
subn
import re # subn 替换并返回元祖(替换结果,替换个数) ret = re.subn('\d+','H','alex123wusir456') print(ret) #('alexHwusirH', 2)
-
match
import re # 内容匹配的时候,要求用户输入11为手机号码,^手机号码正则 $ 与search 功能相近,默认首位加^,态度不同 # match('手机号正则$','123eva456taibai') 规定这个字符号必须是什么样的 # search('^手机号正则$','123eva456taibai') 用来寻找这个字符串中是不是含有满足条件的子内容 ret = re.match('\d+','123eva456taibai') print(ret.group()) #123 ret = re.search('^\d+','123eva456taibai') print(ret.group()) #123
-
compile
import re # compile --> 节省代码时间的工具 # 假如同一个正则表达式要被使用多次 # 节省了多次解析同一个正则表达式的时间 ret = re.compile('\d+') res1 = ret.search('123alex37176') print(res1) #<re.Match object; span=(0, 3), match='123'> print(res1.group()) #123 res2 = ret.findall('123alex37176') print(res2) #['123', '37176']
-
finditer
import re # finditer --> 节省空间 将finditer结果存入迭代器,for遍历ret,通过.group()读取数据 ret = re.finditer('\d+','agks1ak018093') print(ret) #<callable_iterator object at 0x0000029B0EFEB730> for i in ret: print(i.group()) # 1 # 018093
-
finditer 与 compile 的使用
import re # 先compile(如果没有重复使用一个正则表达式,也不能节省空间) # 再finditer ret = re.compile('\d+') res = ret.finditer('agks1ak018as093') for r in res: print(r.group()) # 1 # 018 # 093
-
底层逻辑简介:
# 思考: # 为什么列表不能用insert # 为什么列表不能用pop(n) # 为什么索引取值需要从0开始
-
评判程序员的标准:
-
功能
-
性能
-
时间
- 你要完成一个代码所需要执行的代码行数
- 你在执行代码的过程中,底层程序是如何工作的
-
空间
- 占用了宝贵的内存条资源
- 影响的是程序的执行效率
-
-
用户体验
-
-
re模块的拾遗
-
分组命名
-
方便查找所需要的字段
# 分组命名 方便查找所需要的字段 import re # (?P<名字>正则表达式) # ret.group('名字') ret = re.search('\d(\d)\d(\w+?)(\d)(\w)\d(\d)\d(?P<name1>\w+?)(\d)(\w)\d(\d)\d(?P<name2>\w+?)(\d)(\w)','123abc45678agsf_123abc45678agsf123abc45678agsf') print(ret.group('name1')) print(ret.group('name2'))
-
-
分组命名的引用
# 定义分组命名(?P<名字>正则表达式) # 引用分组命名(?p=名字)
import re exp = '<abc>akd7008&(&*)hgdwuih</abb>008&</abc>(&*)hgdwuih</abd>' ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',exp) print(ret) # <re.Match object; span=(0, 40), match='<abc>akd7008&(&*)hgdwuih</abb>008&</abc>'> print(ret.group()) # <abc>akd7008&(&*)hgdwuih</abb>008&</abc> import re exp = '<abc>akd7008&(&*)hgdwuih</abc>008&(&*)hgdwuih</abd>' ret = re.search(r'<(\w+)>.*?</\1>',exp) print(ret) #<re.Match object; span=(0, 30), match='<abc>akd7008&(&*)hgdwuih</abc>'> ret = re.search('<(\w+)>.*?</\1>',exp) #要加转义字符!!!!!!!!!! \1有特殊意义 print(ret) #None ret = re.findall('\d+(?:\.\d+)?','1-2*(60+(-40.35/5)-(-4*3))') print(ret) #['1', '2', '60', '40.35', '5', '4', '3'] ret = re.findall('[+-]?\d+\.\d+|\d+','1-2*(60+(-40.35/5)-(-4*3))') print(ret) # ['1', '2', '60', '-40.35', '5', '4', '3'] ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))") print(ret) ret = ['1', '2', '60', '', '5', '4', '3','',''] ret.remove('') #列表中有多个空元素,remove只能去除一个 print(ret) ret = filter(lambda n:n,ret) #内置函数filter去除空元素,if n 返回 n print(list(ret))
-
分组命名的规则
# (?P<名字>正则表达式) (?p=名字) # ret.group('名字') # 取消显示优先级(?:)
-
-
带参数的装饰器
-
# 需要让装饰器实现其他功能或者传递参数时,可以在装饰器外再次嵌套一层外层函数,从而达到传参或更改装饰器逻辑的目的
def outer(flag): def timer(func): def inner(*args, **kwargs): if flag: print(''' 執行函數之前要做的''') re = func(*args, **kwargs) if flag: print(''' 執行函數之後要做的''') return re return inner return timer @outer(False) def func(): print(111) func()
-
-
递归函数
-
递归函数初识
- 递归的定义:在一个函数里再调用这个函数本身
count = 0 def func(): global count count += 1 print(count) func() print(456) func()
-
RecursionError
# 递归的最大深度1000层:为了节省内存空间,不让用户无限使用内存空间 # 1.递归要尽量控制次数,如果需要很多层递归才能解决的问题,不适合用递归解决 # 2.循环和递归的关系 # 递归不是万能的 # 递归相比循环来说更占内存 # 修改递归的最大深度 # import sys # sys.setrecursionlimit(10000)
-
你的递归函数必须要停下来
-
递归函数怎么停下来?递归三次结束整个函数
-
一个递归函数想要结束,就必须在函数内写一个return,并且return的条件必须是一个可以达到的条件
count = 0 def func(): global count count += 1 print(count) if count == 3: return f'func完成啦,执行了{count}次' func() print(func()) return后面没有东西时:返回None func()
-
演示环节
# 对上面函数的演示(可能存在语法错误) count = 0 def func1(): count = 1 print(1) if 1 == 3: return func1() def func2(): count = 2 print(2) if 2 == 3: return func2() def func3(): count == 3 print(3) if 3==3: #此处条件满足,执行return return #此处的返回值,返回到上一个函数 func2() func3()
-
-
并不是函数中有return,return的结果就一定能够在调用函数的外层函数接收到
def func(count): count += 1 print(count) if count == 4: return 4 ret = func(count) print(count,':',ret) return ret print(func(1))
-
演示环节:
# # 对上面函数的演示(可能存在语法错误) def func(1): 1 += 1 print(2) if 2 == 4: return 4 ret = func(2) #count = 2 运行下一个函数 ret = func(2)= func(3) = 4 print(count,':',ret) #打印 2:4 return ret #4 def func(2): 2 += 1 print(3) if 3 == 4: return 4 ret = func(3) #count = 3 运行下一个函数 ret = func(3) = 4 print(count,':',ret) #打印(3:4) return ret #返回 ret = func(3) = 4 给func(2) def func(3): 3 += 1 print(4) if 4 == 4: return 4 #满足条件,4返回给ret = func(3) ret = func(count) print(count,':',ret) return ret def func(count): count += 1 print(count) #不写 if count == 5: return 5 #满足条件将返回值5 传递给上一层函数 return func(count) #为了层层传递返回值 print(func(1))
-
-
利用递归函数解决计算阶乘问题:
def fin(n): if n ==1 : return n else: return n*fin(n-1) ret = fin(5) print(ret)
-
演示环节:
# 对上面函数的演示(可能存在语法错误) def fin(5): if 5 ==1 : return n else: return 5*fin(5-1) #返回值为5*4*3*2*1 将其返回给fin(5) ret = fin(5) #ret = fin(5) = 5*4*3*2*1 print(ret) #打印 5*4*3*2*1 def fin(4): if 4 ==1 : return n else: return 4*fin(4-1) #返回值为4*3*2*1 将其返回给fin(5-1) ret = fin(5) print(ret) def fin(3): if 3 ==1 : return 3 else: return 3*fin(3-1) #返回值为3*2*1 将其返回给fin(4-1) ret = fin(5) print(ret) def fin(2): if 2 ==1 : return 2 else: return 2*fin(2-1) #返回值为2*1 将其返回给fin(3-1) ret = fin(5) print(ret) def fin(1): if 1 ==1 : return 1 #返回值1传递给fin(2-1) else: return n*fin(n-1) ret = fin(5) print(ret)
-
-
04 今日总结
- re模块结尾
- findall
- search
- compile
- finditer
- split
- sub
- subn
- match
- re模块的拾遗
- 分组命名
- 分组命名的引用
- 分组命名的规则
- 带参数装饰器
- 就是在原有装饰器外面,再加一层外层函数嵌套,可以传参
- 标准代码
- 递归函数
- 基础
- 结束 return
- 利用递归解决阶乘问题