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个分组中的内容

03 今日内容

  1. 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开始
    
  • 评判程序员的标准:

    • 功能

    • 性能

      • 时间

        • 你要完成一个代码所需要执行的代码行数
        • 你在执行代码的过程中,底层程序是如何工作的
      • 空间

        • 占用了宝贵的内存条资源
        • 影响的是程序的执行效率
    • 用户体验

  1. 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('名字')
      # 取消显示优先级(?:)
      
  2. 带参数的装饰器

    • # 需要让装饰器实现其他功能或者传递参数时,可以在装饰器外再次嵌套一层外层函数,从而达到传参或更改装饰器逻辑的目的
      
      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()
      
  3. 递归函数

    • 递归函数初识

      • 递归的定义:在一个函数里再调用这个函数本身
      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
    • 利用递归解决阶乘问题

05 预习内容

posted @ 2020-08-03 10:06  Redbean1231  阅读(84)  评论(0编辑  收藏  举报