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)
     
    
    
    




      
  • 相关阅读:
    2019 SDN上机第7次作业
    第01组 Beta冲刺(4/5)
    第01组 Beta冲刺(3/5)
    第01组 Beta冲刺(2/5)
    第01组 Beta冲刺(1/5)
    2019 SDN上机第6次作业
    2019 SDN上机第5次作业
    SDN课程阅读作业(2)
    第01组 Alpha事后诸葛亮
    第01组 Alpha冲刺(6/6)
  • 原文地址:https://www.cnblogs.com/echo2019/p/10180528.html
Copyright © 2011-2022 走看看