• Python零散知识点


    零散知识点

    一:代码块

    是一种优化机制,了解直到就可以了,对于实际编码影响不大

    如果在cmd终端里面,每一个>>>是一个代码块,这个比较特殊。代码放在pycharm中运行,又有自己的优化,-5-256的优化空间会变得更长,因此没有准确答案,知道有这个优化就可以了,具体是优化到哪个边界无序在意。

    每个函数都是一个代码块

    类也是一个代码块

    代码块缓存机制

    同一个代码块重复出现的对象在第一次出现的时候就会缓存下来,方便重复使用

    不同代码块缓存有边界,例如-5-256之间的数字会共享内存,str也有缓存规则知道即可,具体是什么不用在意

    指定驻留

    intern()只能用于str的指定驻留,help(intern)查看

    指定任意内容添加到数据池当中,让其在内存中只有一个对象,类似于单例。

    from sys import intern
    a = 'hello!@'
    b = 'hello!@'#字符串不符合缓存机制,因此开2个对象空间
    print("1",a is b)##False
    a = intern('hello!@'*20)#指定驻留之后
    #b = 'hello!@'*20这样做拿到的不是小数据池里面的对象,因为上来解释器看不合符规则,直接就开新内存了
    b = intern('hello!@'*20)#这样子做就是指定到小数据池里面看有没有,没有创建,有则直接用。
     print("2",a is b)#True

    因为只能用于str,因此通用的单例模式不能用intern。因此用到的机会也不多。

    二:深浅拷贝

    1:只要是拷贝一定会开地址内存,但是没有人关心变量地址内存,只关心数据的内存地址。

    深浅拷贝不要用在基本数据类型中,因为都是不可变类型,且大多数都能用缓存机制,因此拷贝他们没有多大的意义。

    拷贝多用在比较复杂的对象,例如list set tuple dict 以及定义类型。

    首先要知道python都是数据外置,例如列表,它的每个索引位都是4bytes,里面只存放数据的内存地址,这样就可以以不变应万变。

    随便数据以及数据类型怎么变,反正列表索引的内存地址是不变的,只要存放的地址你保存好即可。至于地址怎么变的有解释器帮我们完成。

    a1=[1,2,3]

    a2=copy(a1)#无论是深拷还是浅拷贝,a2和a1的内存地址一定不同

    除了基本数据类型,只要是拷贝一定就会开新的内存。

    2:分清拷贝和赋值

    a=b=100#这是赋值

    a=100

    b=copy(a)#拷贝,但是从不可变数据类型中看不出来,觉得没有差别。

    a=【1,2,3】

    b=a#这是赋值

    b=copy(a)#此时拷贝,外壳一定拷贝,但是里面的数据就令看,浅拷贝只拷贝外壳,数据是共享的。

    3:深浅拷贝的差异在于对内部元素知否进行再拷贝

    但是无论是深拷贝还是浅拷贝对于不可变数据类型都不会再拷贝,因为不可变,没有必要再多于的拷贝一份。

    只有可变数据类型,且是深拷贝,才会再拷贝一份。

    l1=[1,2,3,[1,2,3],(1,2,3)]

    对l1进行浅拷贝,只会拷贝最外层的壳,里面所有元素都不会再拷贝

    对l1深拷贝,只会拷贝里面的【1,2,3】列表,(1,2,3)不会开内存再拷贝,因为他不可变。1,2,3前3个元素也是不可变的因此也不会拷贝。

    from copy import copy
    from copy import deepcopy
    l1 = [1,2,3,(12,3,3),[1,2,3]]
    l2 = l1# 这不是浅拷贝这是变量赋值
    print(id(l1)==id(l2))
    l3 = copy(l1)
    print(id(l3))
    l1[2]=5
    print("l1=",l1)
    print("l2=",l2)
    print("l3=",l3)
    print(id(l1[0])==id(l3[0]))
    结果:
    True
    1346854053832
    l1= [1, 2, 5, (12, 3, 3), [1, 2, 3]]
    l2= [1, 2, 5, (12, 3, 3), [1, 2, 3]]
    l3= [1, 2, 3, (12, 3, 3), [1, 2, 3]]
    True
    结论:赋值和拷贝有着明显的区别。
    尽管l1改变了值,l3并没有发生变化,因为是手动改变了赋值而已。但是看到l1和l3的第一个元素的内存还是共享的。
    4:切片和浅拷贝
    l1 = [1, 2, 3, 4, ['alex']]
    l2 = l1[:]#切片是浅拷贝,只要不是明确调用deepcopy()都是浅拷贝
    #和l2 = l1.copy()效果是一样的
    print(l2)
    print(id(l1)==id(l2))
    print(l1[4] is l2[-1])
    

     结果:

    [1, 2, 3, 4, ['alex']]

    False

    True

    [1:]则是拷贝一部分而已。

    5:深拷贝

    from copy import deepcopy
    l1 = [1,2,3,(12,3,3),[100]]
    dd = deepcopy(l1)
    print(l1)
    print(l1[0] is dd[0])#int是不可变数据类型所以没有开内存
    print(l1[-1] is dd[-1])#因为末尾元素是list类型是可变数据类型所以开了新的数据内存
    print(l1[3] is dd[3])
    

      结果:

    [1, 2, 3, (12, 3, 3), [100]]

    True

    False

    True

    深拷贝只要是不可变类型都会再拷贝一遍外壳。

    看十遍不如自己写一遍!巩固基础,纵横开拓!
  • 相关阅读:
    hdu 4144 状态压缩dp
    hdu 4118 树形dp
    hdu 4115 2-SAT判定
    hdu 4085 斯坦纳树
    hdu 3311 斯坦纳树
    hdu 4081 最小生成树+树形dp
    hdu 4424 并查集
    洛谷P2661信息传递
    洛谷P2746校园网
    树状数组模板
  • 原文地址:https://www.cnblogs.com/gyxpy/p/11810058.html
Copyright © 2020-2023  润新知