zoukankan      html  css  js  c++  java
  • day 21 内存管理,正则

    一、内存管理

    1、垃圾回收

    不能被程序访问到的数据,就称之为垃圾。

    2、引用计数

    引用计数是用来记录值得内存地址被记录的次数

    每一次对值地址的引用都可以使得该值的引用计数+1

    每一次对值地址的释放都可以使得该值的引用计数-1

    当一个值的引用计数为0时,该值就会被系统的垃圾回收机制回收

    a=10;b=10  #当要将两个语句放在一行,需要使用分号;
    print(id(a),id(b))
    #8791461192816  8791461192816  使用的是同一个内存地址
    
    del a    #此时并没有将堆区10这个内存地址删除掉,只是将这个值得引用计数值减了1,此时的10的内存地址的计数为1
    del b    #此时堆区10的内存地址的计数为0
    
    当引用计数为0时,存在一个时间,一个阈值,当满足这两种情况下,垃圾回收机制会优化堆区10这个内存地址,将其删除。
    View Code

    3.循环导入

    #列表的循环引用
    lis1=[10]
    lis2=[20]
    lis1.append(lis2)
    lis2.append(lis1)
    print(lis1,lis2)
    #[10, [20, [...]]]  [20, [10, [...]]]
    #此时二者循环引用
    
    del lis1
    del lis2
    #此时删除了两个变量名,但是内部堆区的值得地址还存在,其值的引用计数都为1(二者相互引用),无法删除,此为循环引用。该引用会导致内存泄漏,对于这些不需要的值,系统会利用标记删除来清除内存中的地址,释放空间。
    

    4.标记删除

    标记:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,存放到新的内存空间中。

    删除:删除的过程将遍历堆中所有的对象,将之前所有的内容全部清除,之前被标记的对象会被复制新的一份保存在新的空间。

    5.分带回收(优化机制)

    分代:指的是根据存活时间来为变量划分不同的等级(也就是不同的代)

    新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,被垃圾回收机制扫描的频率越低
    分代解释

    回收:任然使用引用计数作为回收的依据

    二、正则

    正则:就是带语法的字符串,用来匹配目标字符串得到想要的字符串结果

    1.正则就是字符串,可以为带r的原意字符串

     s = "123454http://www.baidu.com/12htp46"

    res = re.findall(r'http://www.baidu.com/', s

    #此处的r为原意字符串

    print(res)

    2.正则语法

    #转义字符    在正则中,\代表匹配
    print(re.findall(r'\a',r'123abc'))
    # \a  此处多出来一个是正常的,显示效果,本质上为a
    
    import re
    print(re.findall(r'd',r'123abc'))  #数字
    print(re.findall(r'[0-9]',r'123abc')) #0-9
    print(re.findall(r'D',r'123abc'))    #非数字
    print(re.findall(r'[A-z]',r'123abc')) #A到z 根据ascii 在其中
    print(re.findall(r'[A-Z]|[a-z]',r'123abc'))#A-Z或a-z
    print(re.findall(r'[A-Za-z]',r'123abc'))#A-Z或a-z
    print(re.findall(r'[A-Za-z0-9好]',r'1好23abc'))#字母和数字 #重点掌握
    
    print(re.findall(r'w',r'1好_23*abc'))#字母+数字+下划线
    print(re.findall(r'W',r'1好_23*abc'))#与w相反
    print(re.findall(r's','1好_23
    	fv
    *abc'))#所有空白,换行,制表符,回车符  不需要加r
    print(re.findall(r'S','1好_23
    	*abc'))#所有可见字符  不需要加r
    print(re.findall(r'.','1好_2 3
    	fv
    *abc'))#所有单个字符,刨除换行符
    单个字符
    print(re.findall(r'[a-z]{2}',r'123\qwtrrererf'))#a-z里两个两个的寻找
    print(re.findall(r'r{2,}',r'123\qwtrrrerrfrr'))#['rrr', 'rr', 'rr'] 贪婪匹配
    print(re.findall(r'r{2}',r'123\qwrrrerrfrr'))#['rr', 'rr', 'rr']  连续的
    print(re.findall(r'r{1,2}',r'123\qwrrrerrfrr'))#['rr', 'r', 'rr', 'rr'] 最少匹配1次,最多匹配2次
    # {n} n是一个非负整数。匹配确定的n次。
    # {n,} n是一个非负整数。至少匹配n次。
    # {n,m}  m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。
    
    print(re.findall(r'qw*',r'123\qwqeqwtqwqw'))#['qw', 'q', 'qw', 'qw', 'qw']
    #匹配前面的子表达式任意次,=={,n} 0到n个,贪婪匹配
    print(re.findall(r'qw+',r'123\qwqeqwtqwqw'))#['qw', 'qw', 'qw', 'qw']
    #匹配前面的子表达式一次或多次 =={1,n} 1到n个, 贪婪匹配
    print(re.findall(r'qw?',r'123\qwqeqwtqwqw'))#['qw', 'q', 'qw', 'qw', 'qw']
    #匹配前面的子表达式零次或一次 =={0,1}  0个到1个  贪婪匹配
    print(re.findall(r'qw?',r'123\qwwwweqwtwqqwqw')) #['qw', 'qw', 'q', 'qw', 'qw']
    print(re.findall(r'qw+',r'123\qwwwweqwtwqqwqw')) #['qwwww', 'qw', 'qw', 'qw']
    print(re.findall(r'qw*',r'123\qwwwweqwtwqqwqw')) #['qwwww', 'qw', 'q', 'qw', 'qw']
    多个字符

    3.正则的多行匹配(字符串不能使用r来保持原义了)

    print(re.findall(r'^http://.+/$', 'http://www.baidu.com/
    http://www.sina.com.cn/', re.M))
    #['http://www.baidu.com/', 'http://www.sina.com.cn/']
    print(re.findall(r'.', 'http://www.baidu.com/
    http://www.sina.com.cn/', re.S))  # .结合S 可将字符串里所有字符找出来
    
    
    # ^: 以什么开头 $: 以什么结尾  结合 flags=re.M  可以按
    来完成多行匹配
    # re.S:将
    也能被.匹配  re.I:不区分大小写
    

      

    4.分组语法

    # 1.从左往右数数 ( 进行编号,自己的分组从1开始,group(0)代表匹配到的目标整体
    # 2.(?: ... ):取消所属分组,()就是普通(),可以将里面的信息作为整体包裹,但不产生分组
    import re
    regexp = re.compile('(?:(?:http://)((.+))/)')  # 生成正则对象   此处的()用来转义,下面的字符串自带了括号
    target = regexp.match('http://(www.baidu.com)/')
    print(target.group(0)) #http://(www.baidu.com)/
    print(target.group(1)) #www.baidu.com
    
    其他函数
    re模块常用方法
    findall 从左往右查找所有满足条件的字符 返回一个列表
    search 返回第一个匹配的字符串 结果封装为对象 span=(0, 5) 匹配的位置 match匹配的值
    match 匹配行首 返回值与search相同 若行首不存在,则返回None
    对于search match 匹配的结果通过group来获取
    compile 将正则表达式 封装为一个正则对象 好处是可以重复使用这个表达式
    split使用正则表达式来切分字符串

    5、拆分

    print(re.split('s','123 456 789 000'))

    #['123', '456', '789', '000']      存在空格

     6.替换

     1.不参与匹配的原样带下,即分组里没包含在内的字符,会给其返回值 
    2.参与匹配的都会被替换为指定字符串
     3.在指定字符串值
    um拿到具体分组  
    4.其他字符串信息都是原样字符串 除了
    um
    
    import re
    print(re.sub('([a-z]+)(d+)(.+)',r'132','abc123你好'))
    #abc你好123 
    
    
    print(re.sub('[0-9]+','数字','abc123你好'))  #注意+的添加
    #abc数字你好
    

      

    res = re.findall('<([a-z]{1,3})>(w*?)</[a-z]{1,3}>', '<a>abc</a><b>123</b>')
    print(res)  # [('a', 'abc'), ('b', '123')]
    
    #('a', 'abc')  前者的a是第一个组产生的,后面的abc是第二个组产生的
    #('b', '123')  前者的b是第一个组产生的,后面的123是第二个组产生
    
    逻辑点:正则表达式里的三个条件是整体匹配所要匹配的字符串,当三个条件都满足时,会记录当前的结果,此时程序继续往后跑,再次遇到符合条件的字符串,继续记录,一直检索到字符串最后。  表达式里的条件不是满足一次就截止,且不是找齐满足条件的最大范围,只要符合要求,就将其值记录下来!!!
    import re
    res = re.match('(d{3})(d{3})(d{3})', '123456789111222333')
    print(res.group(0)) #123456789
    print(res.group(1)) #123
    print(res.group(2)) #456  
    print(res.group(3)) #789
    
    
    res = re.findall('(d{3})(d{3})(d{3})', '123456789111222333')
    print(res)  #[('123', '456', '789'), ('111', '222', '333')]
    
    
    
    
    #二者的区别:match 仅获取第一次匹配的内容  findall会一直更新获取匹配的内容
    

      

     

  • 相关阅读:
    《R语言实战》读书笔记--第五章 高级数据管理
    《R语言实战》读书笔记--第四章 基本数据管理
    《R语言实战》读书笔记--第三章 图形初阶(二)
    《R语言实战》读书笔记--第三章 图形初阶(一)
    《R语言实战》读书笔记--第二章 创建数据集
    《R语言实战》读书笔记--第一章 R语言介绍
    《R语言实战》读书笔记--为什么要学
    《算法导论》读书笔记--第1、2章课后题
    《算法导论》读书笔记--第二章 2.3 设计算法
    Mysql重复数据查询置为空
  • 原文地址:https://www.cnblogs.com/changwenjun-666/p/10719691.html
Copyright © 2011-2022 走看看