zoukankan      html  css  js  c++  java
  • day 06 列表去重, 数据类型的补充,编码,深浅copy

    因为重要,所以放前面

    列表去重

    l1 = [1, 2, 3, 4, 5]
    l2 = [3, 4, 5, 6, 7]
    set = list(set(l1 + l2))      # set自动去重,然后变成list类型
    print(set)     #  [1, 2, 3, 4, 5, 6, 7]

    1、 id    is    ==

    == 是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等。 如果内存地址相等,那么这两边其实是指向同一个内存地址。

    l1 = [1, 2, 3]
    l2 = [1, 2, 3]
    print(l1, l2)        
    print(id(l1), id(l2))      # 值相同,ID不同
    l1 = [1, 2, 3]
    l2 = [1, 2, 3]
    print(l1 == l2)  # True
    print(l1 is l2)  # False

    可以说如果内存地址相同,那么值肯定相同,但是如果值相同,内存地址不一定相同。

    代码块:   了解

    Python程序是由代码块构造的。块是一个python程序的文本,他是作为一个单元执行的。

    代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。

    而作为交互方式输入的每个命令都是一个代码块。

    对于一个文件中的两个函数,也分别是不同的代码块

    代码块的缓存机制  了解 

    代码块的缓存机制的适用范围: int(float),str,bool

    int(float):任何数字在同一代码块下都会复用。

    bool:True和False在字典中会以1,0方式存在,并且复用。

    str:几乎所有的字符串都会符合缓存机制

    小数据池:  提升效率,节约内存

    Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。

    python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。

    其实,无论是缓存还是字符串驻留池,都是python做的一个优化,就是将~5-256的整数,和一定规则的字符串,放在一个‘池’(容器,或者字典)中,无论程序中那些变量指向这些范围内的整数或者字符串,那么他直接在这个‘池’中引用,言外之意,就是内存中之创建一个。

    优点:能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘池’里拿来用,避免频繁的创建和销毁,提升效率,节约内存。

    总结:

      如果在同一代码块下,则采用同一代码块下的换缓存机制。

      如果是不同代码块,则采用小数据池的驻留机制

    # pycharm 通过运行文件的方式执行下列代码:  这是在同一个文件下也就是同一代码块下,采用同一代码块下的缓存机制。
    i1 = 1000
    i2 = 1000
    print(i1 is i2)  # 结果为True 因为代码块下的缓存机制适用于所有数字
    通过交互方式中执行下面代码:   # 这是不同代码块下,则采用小数据池的驻留机制。
    >>> i1 = 1000
    >>> i2 = 1000
    >>> print(i1 is i2)
    False  # 不同代码块下的小数据池驻留机制 数字的范围只是-5~256.
    # 虽然在同一个文件中,但是函数本身就是代码块,所以这是在两个不同的代码块下,不满足小数据池(驻存机制),则指向两个不同的地址。
    def func():
        i1 = 1000
        print(id(i1))  # 2288555806672
    
    def func2():
        i1 = 1000
        print(id(i1))  # 2288557317392
    
    func()
    func2()

    2、数据类型补充: int, str, bool,list,tuple,dict,set。

    # 数据类型之间的转换:
    # str ---> list split

    # list ---> str join

    # bool :False 0 '' [] () {} set()

    list <----> tuple

    # list <--->  tuple
    l1 = [1,2,3]
    tu1 = tuple(l1)
    l2 = list(tu1)
    print(tu1)
    print(l2)

    list <------ dict

    # list <---- dict
    dic1 = {'name': 'alex', 'age': 12}
    print(list(dic1))

    list <------dict

    # list <---- dict
    dic1 = {'name': 'alex', 'age': 12}
    print(list(dic1))

    list <------>  set

    # list <---> set ***
    li = [1, 2, 3, 4, 5]
    set = set(li)
    print(set, type(set))
    set = {1, 2, 3, 4, 5}
    list = list(set)
    print(list)

    元组补充: 

    元组中只有一个元素并且没有逗号,则他不是元组,与元素数据类型相同。
    tu1 = (1)
    tu2 = (1)
    print(tu1, id(tu1), type(tu1))  # 1 1558496944 <class 'int'>
    print(tu2, id(tu2), type(tu2))  # 1 1558496944 <class 'int'>
    tu1 = (1,)
    tu2 = (1,)
    print(tu1, id(tu1), type(tu1))  # (1,) 2880293370120 <class 'tuple'>
    print(tu2, id(tu2), type(tu2))  # (1,) 2880294252048 <class 'tuple'>

    踩坑题

    坑1:li = [11, 22, 33, 'alex', 55]  将列表中索引为奇数位的元素删除

    错误事例:  

    li = [11, 22, 33, 'alex', 55]
    for index in range(len(li)):
        if index % 2 == 1:
            li.pop(index)
    print(li)                    #  [11, 33, 'alex']   删除的是索引为1,4 的元素
    
    # 原因:pop在删除索引1后,会将后面元素,全部向前提一位 (补空)
    #  解决方法: 循环从后面开始

    解决方法:

    一,从后面开始循环

    li = [11, 22, 33, 'alex', 55]
    for index in range(len(li)-1, -1, -1):
        if index % 2 == 1:
            li.pop(index)
    print(li)

    二,创建新列表,将偶数选出,然后覆盖 li 列表

    li = [11, 22, 33, 'alex', 55]
    l1 = []
    for index in range(len(li)):
        if index % 2 == 0:
            l1.append(li[index])
    li = l1
    print(li)
    总结:在循环一个列表时,最好不要改变列表的大小,这样会影响你的最终结果

    坑二:
     dic = {'k1':1,'k2':2, 'k3': 3, 'name': '太白'}
    将字典中键含有k元素的键值对删除
    错误示例:
    dic = {'k1':1,'k2':2, 'k3': 3, 'name': '太白'}
    for key in dic:
        if 'k' in key:
            dic.pop(key)
    l1 = []
    # 结果报错 dictionary changed size during iteration

    解决方法:

    dic = {'k1': 1, 'k2': 2, 'k3': 3, 'name': '太白'}
    l1 = []
    for key in dic:
        if 'k' in key:
            l1.append(key)
    for k1 in l1:
        dic.pop(k1)
    print(dic)

    总结:dict 在循环一个字典时,不能改变字典的大小,会报错


    编码的进阶:
     ascii,unico,utp-8,gbk四个编码本:
    1,不同的编码之间能否互相识别(报错或者出现乱码)。 不能!!
    2, 规定:文字通过网络传输,或者硬盘存储不能使用Unicode编码方式。 耗内存

    大前提:
    python3x环境:
    唯独str类型:他在内部编码方式是unicode
    所以 python3x中的字符串不能用于直接的网络传输 文件的存储 '中午请我去吃饭'

    补充一个数据类型:bytes类型 与str类型是海尔兄弟。
    为啥要有bytes:
    bytes内部编码方式非unicode

    为啥还要有str? bytes直接就解决了所有问题呀?
    bytes 中文是16进制表示,看不懂。
    英文:
    str:
    表现形式:'alex'
    内部编码:unicode

    bytes:
    表现形式:b'alex'
    内部编码:非unicode

    中文:
    str:
    表现形式:'屌丝'
    内部编码:unicode

    bytes:
    表现形式:b'xe5xb1x8cxe4xb8x9d''
    内部编码:非unicode

    bytes:当你需要网络传输数据,文件存储数据时要考虑到bytes。

    str ---> bytes(gbk utf-8)
    unicode ---> gbk utf-8

    bype 用法:
    s1 = 'alex'
    b1 = b'alex'
    print(b1,type(b1))    # b'alex' <class 'bytes'>
    print(b1.upper())   # b'ALEX'
    
    

    编码之间的转换

    # unicode ---> gbk 字符串 ---> gbk编码方式的bytes
    s1 = '太白'
    b1 = s1.encode('gbk') # 编码
    s2 = b1.decode('gbk') # 解码
    print(s2)
    # unicode ---> utf-8  字符串 ---> utf-8 编码方式的bytes
    s2 = '太白'
    b2 = s2.encode('utf-8')
    s3 = b2.decode('utf-8')
    print(s3)
    # gbk ---> utf-8
    #
    b1 = b'xccxabxb0xd7'  # gbk编码的bytes类型
    s = b1.decode('gbk')
    b2 = s.encode('utf-8')  # utf-8编码的bytes类型
    print(b2)

    深浅copy

    浅copy,在内存中创建一个新的list(dict),但是新的列表里面的元素还是与原列表共用一个

    # 浅copy
    # 在内存中创建一个新的list(dict),但是新的列表里面的元素还是与原列表共用一个。
    l1 = [1, 'alex', [11, 22]]
    l2 = l1.copy()
    print(id(l1), id(l2))     #  1893402849992 1893402850760
    l1.append(33)
    print(l1, l2)             # [1, 'alex', [11, 22], 33] [1, 'alex', [11, 22]]
    print(id(l1[0]))          # 1558496944
    print(id(l2[0]))          # 1558496944
    print(id(l1[-1]))         # 1558497968
    print(id(l2[-1]))         # 1893402827784
    print(l1 is l2)           # print(l1 is l2)  

    深COPY

    深copy会在内存中对原列表(dict)以及列表里面的可变的数据类型重新创建一份,而列表中不可变的数据类型还是沿用原来的

    import copy
    l1 = [1, 'alex', [11,22]]
    l2 = copy.deepcopy(l1)
    # l1[0] = 1000
    print(l1)
    print(l2)
    # print(id(l1))
    print(id(l2))
    print(id(l1[-1]))  # 2190627337480
    print(id(l2[-1]))  # 2190627338888
    print(id(l1[0]))
    print(id(l2[0]))
    l1[-1].append(666)
    print(l1)
    print(l2)
     
    
    
    




      
  • 相关阅读:
    实用机器学习 跟李沐学AI
    Explicitly drop temp table or let SQL Server handle it
    dotnettransformxdt and FatAntelope
    QQ拼音输入法 禁用模糊音
    (技术八卦)Java VS RoR
    Ruby on rails开发从头来(windows)(七)创建在线购物页面
    Ruby on rails开发从头来(windows)(十三)订单(Order)
    Ruby on rails开发从头来(windows)(十一)订单(Order)
    新员工自缢身亡,华为又站到了风口浪尖
    死亡汽油弹(Napalm Death)乐队的视频和来中国演出的消息
  • 原文地址:https://www.cnblogs.com/echo2019/p/10180528.html
Copyright © 2011-2022 走看看