python-day17~18_递归_正则表达式1,
#递归函数
#   了解什么是递归:在函数中调⽤⾃⾝函数
#   最⼤递归深度默认是997/998 —— 是python从内存⾓度出发做得限制
#RecursionError: maximum recursion depth exceeded while calling a Python object
# 递归的错误,超过了递归的最⼤深度
# import sys
# sys.setrecursionlimit(1000000)
# n = 0
# def story():
#    global n
#    n += 1
#    print(n)
#    story()
# story()
# 如果递归次数太多,就不适合使⽤递归来解决问题
# 递归的缺点:占内存
# 递归的优点:会让代码变简单
# alex 多⼤ n = 1 age(1) = age(2)+2 = age(n+1) + 2
# alex⽐egon⼤两岁
# egon多⼤? n = 2 age(2) = age(3) + 2 = age(n+1) +2
# egon⽐wusir⼤两岁
# wusir多⼤ n = 3 age(3) = age(4) + 2 = age(n+1) +2
# wusir⽐⾦⽼板⼤两岁
# ⾦⽼板多⼤?
# ⾦⽼板40了 n = 4 age(4) = 40
# n = 4 age(4) = 40
# n <4 age(n) = age(n+1) +2
def age(n):
  if n == 4:
    return 40
  elif n >0 and n < 4:
    age(n+1) + 2
#
print(age(1))
2,递归函数,每个调⽤结果都⽤return返回,防⽌返回不回值
# ⼆分查算法必须处理有序的列表
# l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def find(l,aim,start = 0,end = None):
  end = len(l) if end is None else end
  mid_index = (end - start)//2 + start
  if start <= end:
    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 '不到这个值'
ret= find(l,44)
print(ret)
3,正则表达式
tool.chinaz/regex/
re模块
import re
[A-Za-z0-9]字母和数字,可同时放n个字符组
常⽤元字符
代码说明
.匹配除换⾏符以外的任意字符
\w匹配字母或数字或下划线word
\s匹配任意的空⽩符space
\d匹配数字digit
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束
常⽤限定符
代码/语法说明
*重复零次或更多次
+重复⼀次或更多次
?重复零次或⼀次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
常⽤反义词
python正则表达式判断代码/语法说明
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空⽩符的字符
\D匹配任意⾮数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这⼏个字母以外的任意字符
.\b
限定符要放在元字符后⾯,且只对贴在⼀起的最近的元字符有效
\w+\d+  #前⾯的+只对字母有效,后⾯的+只对数字有效
\d{11}  #匹配有11位长度的数字
\\n 匹配\n
.*?要与其它字符配合写(贪婪匹配),如:
<.*?>  匹配<script><scewe32ript>这2项  # 加上?为将贪婪匹配模式转为⾮贪婪匹配模式,会匹配尽量短的字符串.*?x 匹配任意长度字符,直到遇到x字符,就匹配完成
r'\\n' 匹配r'\n'   # 在字符串之前加r,让整个字符串不转义
?是特别限定符:
1)限定符后加?,取最少的动作,即惰性运算;2)⽤?:取消权限
# ret = re.findall('[a-z]+', 'eva egon yuan')
# # 返回所有满⾜匹配条件的结果,放在列表⾥
# print(ret)  #输出 ['eva', 'egon', 'yuan']
# ret = re.search('a', 'eva egon yuan')
# if ret:
#   up())
# 从前往后,到第⼀个就返回,返回的变量需要调⽤group才能拿到结果
# 如果没有到,那么返回None,调⽤group会报错
# ret = re.match('[a-z]+', 'eva egon yuan')
# if ret:
#    up())  #输出:eva
# match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回第⼀个匹配的变量。
# 匹配的内容需要⽤group才能显⽰
# 如果没匹配上,就返回None,调⽤group会报错
# ret = re.split('[ab]', 'abcd')
# # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
# print(ret)    #输出: ['', '', 'cd']
# ret = re.sub('\d', 'H', 'eva3egon4yuan4',1)
#将数字替换成'H',参数1表⽰只替换1个(从左往右数)
# print(ret)   #evaHegon4yuan4
# ret = re.subn('\d', 'H', 'eva3egon4yuan4',2)
# #将数字替换成'H',返回元组(替换的结果,替换了多少次)
# print(ret)  #输出:('evaHegonH5yuan2', 2)
# obj = repile('\d{3}')
# #将正则表达式编译成为⼀个正则表达式对象,规则要匹配的是3个数字
# ret = obj.search('abc123eeee') #正则表达式对象调⽤search,参数为待匹配的字符串
# up())  #结果: 123
# ret = obj.search('abcashgjgsdghkash456eeee3wr2') #正则表达式对象调⽤search,参数为待匹配的字符串# up()) #结果: 456
# import re
# ret = re.finditer('\d', 'ds3sy4784a')    #finditer返回⼀个存放匹配结果的迭代器
# print(ret) # <callable_iterator object at 0x10195f940>
# # print(next(ret).group()) #查看第⼀个结果
# # print(next(ret).group()) #查看第⼆个结果
# # print([i.group() for i in ret]) #查看剩余的左右结果
# for i in ret:
#    up())
上述函数的flag
flags有很多可选值:
re.I(IGNORECASE)忽略⼤⼩写,括号内是完整的写法
re.M(MULTILINE)多⾏模式,改变^和$的⾏为
re.S(DOTALL)点可以匹配任意字符,包括换⾏符
re.L(LOCALE)做本地化识别的匹配,表⽰特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使⽤
re.U(UNICODE) 使⽤\w \W \s \S \d \D使⽤取决于unicode定义的字符属性。在python3中默认使⽤该flag
re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多⾏的,忽略空⽩字符,并可以添加注释
如:def findall(pattern, string, flags=0)
5,分组 ()与或|[^]
import re
# ret = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105************')
# up())
# up(1))
# up(2))
# import re
#
# ret = re.findall('www.(baidu|oldboy)', 'www.oldboy')
# print(ret)    # 输出:['oldboy'] 这是因为findall会优先把匹配结果组⾥内容返回,如果想要匹配结果,取消权限即可#
# ret = re.findall('www.(?:baidu|oldboy)', 'www.oldboy')    #⽤?:取消权限
# print(ret)    #结果: ['www.oldboy']
ret=re.split("\d+","eva3egon4yuan")
print(ret)   #结果: ['eva', 'egon', 'yuan']
ret=re.split("(\d+)","eva3egon4yuan",re.S)
print(ret)   #结果: ['eva', '3', 'egon', '4', 'yuan']分隔部分⼀起输出
6,匹配标签
import re
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
#还可以在分组中利⽤?<name>的形式给分组起名字
#获取的匹配结果可以直接⽤group('名字')拿到对应的值
up('tag_name'))  #结果:h1
up())  #结果:<h1>hello</h1>
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
#如果不给组起名字,也可以⽤\序号来到对应的组,表⽰要的内容和前⾯的组内容⼀致
#获取的匹配结果可以直接⽤group(序号)拿到对应的值
up(1))
up())  #结果:<h1>hello</h1>
7,
三级菜单
menu = {
'北京': {
'海淀': {
'五道⼝': {
'soho': {},
'⽹易': {},
'google': {}
},
'中关村': {
'爱奇艺': {},
'汽车之家': {},
'youku': {},
},
'上地': {
'百度': {},
},
},
'昌平': {
'沙河': {
'⽼男孩': {},
'北航': {},
},
'天通苑': {},
'回龙观': {},
},
'朝阳': {},
'东城': {},
},
'上海': {
'闵⾏': {
'炸鸡店': {}
}
},
'闸北': {
'⽕车战': {
'携程': {}
}
},
'浦东': {},
},
'⼭东': {},
}
menu
menu
def threeLM(dic):
while True:
for k in dic:print(k)
key = input('input>>').strip()
if key == 'b'or key == 'q':return key
elif key in dic.keys() and dic[key]:
ret = threeLM(dic[key])
if ret == 'q': return'q'
threeLM(menu)
递归函数实现三级菜单
递归函数实现三级菜单
学习:
wwwblogs/Eva-j/articles/7228075.html#_label10
a = '1 - 2 * ( ( 6 0 -3 0  +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
import re
def compu(lin):
'''计算字符串中的数字'''
ret2 = re.findall('(?:-?\d+\.\d+)|(?:-?\d+)', lin)  # 拿到所有数字
# print(ret2, len(ret2))
com_alpha = re.findall('[(\+)|\-|(\*)|/]', lin[1:])  # 拿到所有运算符
# print(com_alpha, len(com_alpha))
count = 0
com_alpha_new = []
ret2_new = []
flag_multiply = False
temp = 0
if'*'in com_alpha or'/'in com_alpha:
while count < len(com_alpha):  # 乘除运算后的数字,放到新列表中
if com_alpha[count] == '*':
if flag_multiply == False:
temp = float(ret2[count]) * float(ret2[count + 1])
flag_multiply = True
else:
temp = temp * float(ret2[count + 1])
elif com_alpha[count] == '/':
if flag_multiply == False:
temp = float(ret2[count]) / float(ret2[count + 1])
flag_multiply = True
else:
temp = temp / float(ret2[count + 1])
else:
if flag_multiply:
ret2_new.append(temp)  # temp数字(乘除运算完成)放到新列表中
com_alpha_new.append(com_alpha[count])
flag_multiply = False
else:
ret2_new.append(ret2[count])
com_alpha_new.append(com_alpha[count])  # +-运算符没有运算,原样放到新列表中