• day07-列表补充(深浅copy),元组类型和字典类型的运用


    今日内容:列表补充 元组类型 字典类型

    列表之深浅copy

    深浅copy介绍

    拷贝就是copy,也就是复制的意思。
    深浅拷贝顾名思义就存在深拷贝和浅拷贝两种情况。

    b = ['zz', 'yy']

    a = [1, 2, 3, 4, b]

    浅拷贝:

    a.copy() 或者a[:]这样a列表就完成了一次浅拷贝

    例如:

    list = [1,2,3,4]
    new_list = list.copy()  # ===> 这时会浅copy list 列表 返回一个新的列表new_list
    new_list1 = list[:]
    

    深拷贝:

    import copy
    list = [1,2,3,4]
    new_list = copy.deepcopy(list)  # ===> 这时会深copy list 列表 返回一个新的列表new_list
    

    这样list列表就完成了一次深拷贝。
    浅拷贝list.copy()等价于copy.copy(list)

    深拷贝和浅拷贝的区别

    浅拷贝只拷贝第一层的即l列表的存储数据地址,如果此时b列表(子列表)发生了修改,则new_l列表中b列表的数据也会发生变化,此时数据复制的结果就会不准确.

    浅copy的原理图

    img

    案例:

    l = [11, 22, ['xx', 'yy']]
    new_l = l.copy()  # t等同于new_l = l[:]
    new_l[0] = 00  # 改变的列表对应的元素为11,是一个整型为一个不可变类型的数据,它改变的仅仅是自己,不会影响到原来(关联)的列表
    
    print(l)  # ====> [11, 22, ['xx', 'yy']]
    print(new_l)  # ====>[0, 22, ['xx', 'yy']]
    
    new_l[2][1] = 'zzz'  # 此时改变的是列表中的子列表元素['xx', 'yy'] ,子列表是一个列表类型的数据,为一个可变类型,它不仅会改变自己,也会改变原来(关联)的列表
    print(l)  # ====> [11, 22, ['xx', 'zzz']]
    print(new_l)  # =====> [11, 22, ['xx', 'zzz']]
    print(id(l[0]), id(l[1]), id(l[2]))  # ===> 140718605693504 140718605693856 1699776254536
    print(id(new_l[0]), id(new_l[1]), id(new_l[2]))  # ===> 140718605693504 140718605693856 1699776254536
    

    总结:浅copy一个列表后,如果copy的列表中的元素有可变类型的数据,当改变其中一个列表中的可变类型对应的值,时俩个值都会受影响.而元素的数据类型为不可变的,则不会影响.

    因为声明一个列表的变量时.变量名对应的值是一个索引和索引相对应的元素的值的内存地址,再通过内存地址绑定到索引指向的值,所以当索引指向的值的数据类型为可变的数据类型时,它绑定的值又会延续到下一个索引对应的索引的值的内存地址.也就是说浅copy的元素为可变类型时,它们的子列表的索引对应的内存地址的计数是1,公用一条,

    当发生改变时,计数变为0,重新指向同一个内存地址.

    为了杜绝这种情况,我们需要进行深拷贝,把进行嵌套的所有列表数据都复制一遍,这样不管哪一层数据发生变化,对我们已经复制的数据都不会产生影响。

    深copy底层原理图:

    img

    深copy会将子列表申请一个新的内存空间,值是一样的.避免改一个而牵连俩个列表.

    案例:

    from copy import deepcopy
    l = [11, 22, ['xx', 'yy']]
    new_l1 = deepcopy(l)  # 深copy
    print(id(l[0]), id(l[1]), id(l[2]))  # # ===> 140718605693504 140718605693856 1699776254536
    print(id(new_l1[0]), id(new_l1[1]), id(new_l1[2]))  # ====> 140718605693504 140718605693856 1699780262472
    

    列表内置方法的补充

    需要掌握的

    代码中===>后接的是返回结果

    l_list = [11, 22, 33, 44, 55, 66, 22, 22, 33]
    print(l_list.index(11))  # 列表中的元素对应的索引,返回值是一个索引 ==> 0
    print(len(l_list))  # 列表元素的个数 l.__len__()返回值是一个数字 ==> 9
    
    print(l_list.count(33))  # 列表中元素出现的个数 返回值是一个数字  ==> 2
    print(l_list.clear())  # 清空一个列表  返回值为None ===> None
    print(l_list)  # ===> []
    l_list1 = [11, 22, 33, 99, 88, 44, 55, 66, 77]
    print(l_list1.extend([77, 88]))  # 往列表中添加多个值(值为一个可迭代对象) 返回的是None
    print(l_list1)  # ===> [11, 22, 33, 99, 88, 44, 55, 66, 77, 77, 88]
    print(l_list1.reverse())  # 将列表中的元素,反着存放 返回的是None
    print(l_list1)  # ===> [88, 77, 77, 66, 55, 44, 88, 99, 33, 22, 11]
    print(l_list1.sort())  # 将列表中的元素排序,默认是升序 返回的是None
    print(l_list1)  # ===> [11, 22, 33, 44, 55, 66, 77, 77, 88, 88, 99]
    print(l_list1.sort(reverse=True))  # 降序 将 reverse=True, 返回的是None
    print(l_list1)  # ====> [99, 88, 88, 77, 77, 66, 55, 44, 33, 22, 11]
    

    列表函数(了解)

    序号 函数
    1 cmp(list1, list2)比较两个列表的元素
    2 len(list) 列表元素个数
    3 max(list) 返回列表元素最大值
    4 min(list)返回列表元素最小值
    5 list(seq)将元组转换为列表

    元组类型

    概念:

    • 元组与列表类似,不同之处在于元组的元素不能修改。
    • 元组使用小括号,列表使用方括号。
    • 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

    用途: 元组就相当于一种不可变的列表,所以说元组包含的元素可以是任意类型

    作用:存多个值,对比列表来说,元组不可变(是可以当做字典的key的),主要是用来读

    定义:与列表类型相似,只不过[]换成()

    age=(11,22,33,44,55)  # 本质age=tuple((11,22,33,44,55))
    

    需要注意的是在python中()也可以表示包含的意思,所以,当你使用 i = (1),此时的类型还是整型1
    要想存一个1为元组的类型:需要在数字1后面的加上一个","

    i1 = (1)
    print(i1, type(i1))  # ===> 1 <class 'int'>
    i2 = (1,)
    print(i2, type(i2))  # ====> (1,) <class 'tuple'>
    

    优先掌握的操作:

    提示:详细用法请看前面的列表类型

    # 1、按索引取值(正向取+反向取):只能取
    t_tuple = (11, 22, 33, 44, 55)
    print(t_tuple[0], t_tuple[-1])  # ===> 11 55
    # #2、切片(顾头不顾尾,步长)
    print(t_tuple[0:2])  # ==> (11, 22)
    # #3、长度
    print(len(t_tuple))  # ===> 5
    # #4、成员运算in和not in
    print(11 in t_tuple)  # ===> True
    
    #5、循环
    for t in t_tuple:
        print(t)
    

    修改元组

    元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例

    tup1 = (12, 34.56)
    tup2 = ('abc', 'xyz')
    
    # tup1[0] = 100 # 这样直接修改元组元素操作是非法的。==> TypeError: 'tuple' object does not support item assignment
    
    # 创建一个新的元组
    tup3 = tup1 + tup2
    print(tup3)  # ===> (12, 34.56, 'abc', 'xyz')
    

    删除元组

    元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:

    del tup1  # 手动释放掉了tup1变量名指向的内存地址,计数为0
    print(tup1)  # 再引用会报错 ===>NameError: name 'tup1' is not defined
    

    无关闭分隔符

    任意无符号的对象,以逗号隔开,默认为元组,如下实例:

    print('abc', 11, 22, 'xyz')  # ===> abc 11 22 xyz
    res = 'abc', 11, 11, 'xyz'
    print(type(res))  # ===> <class 'tuple'>
    x, y = 1, 2
    print("Value of x , y : ", x, y)  # ====> Value of x , y :  1 2
    

    字典的数据类型

    字典的介绍:

    字典是另一种可变容器模型,且可存储任意类型对象。

    用途:按照key:value 的方式存放多个值,其中key对value应该有描述性效果

    字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:

    d = {key1 : value1, key2 : value2 }

    键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。

    dict = {'a': 1, 'b': 2, 'b': '3'}
    print(dict['b'])  # ===> 3
    print(dict)  # ===> {'a': 1, 'b': '3'}
    

    值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。

    小知识点:hash与可变不可变是相反的,即kehash的是不可变数据类型,不可hash的为可变数据类型

    数据类型转换

    调用字典的dict()方法转成字典的类型有局限性.必须为可迭代对象类型且遍历后有俩个值的

    例如:

    res = dict([('key', 'value'), ['key1', 'value1']])  # ===> {'key': 'value', 'key1': 'value1'}
    print(res)
    

    字典的俩种声明方式

    d = {}  # 推荐
    print(d, type(d))  # ===> {} <class 'dict'>
    d1 = dict()  # 等同于上方的 d = {}
    print(d1, type(d1))  # ===> {} <class 'dict'>
    

    如何将变量名绑定一个字典类型的值

    语法: dict_obj = {'key1':'value1', 'key2': 'value2'}

    案例: 将同学的消息存放在字典中

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    

    存了值.我们如何取值

    字典中取值的俩种方式:

    因为字典是无序的,所以我们不能通过索引取值

    按照在dict_obj[key]取对应的value

    按照dict_obj.get(key)取对应的value

    区别:取一个不存在字典中的key时,按照[key]的方式会报语法错误,而.get(key)的方式会返回一个None

    案例: 在同学消息字典中取出他的名字

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    print(student_dict[0])  # ==> KeyError: 0
    
    print(student_dict['name'])  # jkey
    print(student_dict.get('name'))  # jkey
    

    当key不存在时

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    # print(student_dict['XXX'])  # 输出 ===> KeyError: 'XXX'
    print(student_dict.get('XXX'))  # 输出 ====> None
    

    因为字典是一个可变类型,所以它的值可以改变

    改字典的值.

    通过dict_obj['key']对相应的value的值进行更改,并且改变原字典

    注意:dict_obj.get('key')只能取值,不能该值.

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    student_dict['name'] = 'liu'
    print(student_dict)  # 输出 {'name': 'liu', 'age': 18, 'habbyies': ['play', 'eat']}
    # student_dict.get('age') = 11  # 该值会报语法错误=== > SyntaxError: can't assign to function call
    

    居然可以改值,是不是也支持添加值呢???

    是的.字典可以添加值

    字典添加值的操作

    因为字典是无序的,并且是以键值对的方式存放,所以我们可以直接通过dict_obj['new_key']=new_value

    是不是和改值一样,只不过此时的key是一个原字典不存在的key,"key"最好是唯一的且字符串的类型

    案例:往学生字典中添加一个性别的数值

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    student_dict['sex'] = 'male'
    print(student_dict)  # 输出 ===>  {'name': 'jkey', 'age': 18, 'habbyies': ['play', 'eat'], 'sex': 'male'}
    

    根据输出结果你可以发现,它是将新的键值对放到字典的最后,这里要提的小知识点是,不管在python2中还是在python3中,字典都是无序的,但是python3中优化了字典的输出.让其看起来像是一个有序的.

    那你都可以改了是不是也可以删呢?

    是的字典支持删值

    方式1:万能删除del

    • 功能:将字典中的变量名和内存地址之间的链接清除,可以是清除一个key:value,也可以是一个字典对象本身
      • 注意:清除了字典对象本身的话,这个变量名就不能被引用了,也就是不能被调用了
    • 语法:
      • del dict_obj或者del dict_obj
    • 没有返回值,用变量名接收还会报错

    案例:将学生字典中的name删除

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    del student_dict['name']
    print(student_dict) # ===> {'age': 18, 'habbyies': ['play', 'eat']}
    

    del 一个字典对象本身

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    del student_dict
    print(student_dict)  # ====>NameError: name 'student_dict' is not defined
    

    方式2: pop()

    • 功能: 删除字典给定键 key 及对应的值
    • 语法:
      • dict_obj.pop(key[,default])
        • key为你要删除的键值对的键--key
        • default:如果没有 key,返回 default 值
    • 返回值为被删除的值。key 值必须给出。 否则,返回 default

    案例:将学生字典中的name删除

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    name = student_dict.pop("name")  # 将key=name的键值对在student_dict删除
    print(name)  # === > jkey
    print(student_dict)  # {'age': 18, 'habbyies': ['play', 'eat']}
    

    方式3: popitem()

    • 功能: 删除一个字典中的最后一个键值对
    • 语法: dict_obj.popitem()
    • 返回的是被删除的最后一个key:value

    案例:随机删除学生字典中的一组键值对

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    student_dict.popitem()  # 随机删除student_dict中的一组键值对
    print(student_dict)  # === > {'name': 'jkey', 'age': 18}
    

    方式4: clear()

    • 功能:清空字典的键值对
    • 语法:dict_obj.clear()
    • 返回一个None

    案例:清空学生字典

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    res = student_dict.clear()  # 清空student_dict
    print(student_dict)  # ====> {}
    print(res)  # ===> None
    

    是不是感觉干掉字典的方式很多,但字典真正用的多的还是增改查

    还有一个很常见的就是和for循环之间的搭配啦

    keys()方法

    • 功能: 以列表返回一个字典所有的
    • 语法:
      • dict.keys()
    • 返回值: 返回一个字典所有的

    案例:打印出学生字典中所有的键--key

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    for student_key in student_dict.keys():  # 遍历出字典student_dict中的所有的key
        print(student_key)
    for s_key in student_dict:
        print(s_key)
        
    '''
    输出结果是一样的:
            name
            age
            habbies
            name
            age
            habbies
    '''
    

    注意:遍历一个字典默认返回的就是字典的键-key

    values()方法

    • 功能: 以列表返回字典中的所有值
    • 语法:
      • dict.values()
    • 返回值: 返回字典中的所有值---value

    案例:打印出学生字典中的所有的值

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    for s_value in student_dict.values():  # 遍历出字典student_dict中所有的值
        print(s_value)
    
    '''
    输出结果为:
            jkey
            18
            ['play', 'eat']
    '''
    

    items()方法

    • 功能: 以列表返回可遍历的(键, 值) 元组数组
    • 语法:
    • dict.items()
    • 返回值: 返回可遍历的(键, 值) 元组数组

    案例:遍历出学生字典中的键值对

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    for key1, value1 in student_dict.items():  # 遍历student_dict 字典中的 所以键值对,返回(key,value)--->这个元组
        print(key1, value1)
    '''
    输出结果:
        name jkey
        age 18
        habbies ['play', 'eat']
    '''
    

    字典还有其他很多内置函数和方法哦

    接着往下看

    字典内置方法&函数(补充)

    方法

    copy()方法

    • 功能: 对一个字典的浅复制
    • 语法:
      • dict.copy()
    • 返回值: 返回一个浅复制过来的字典

    案例:将学生字典,浅copy一份出来

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    c_student_dict = student_dict.copy()  # 对学生字典student_dict进行浅copy并绑定给变量名c_student_dict
    print(c_student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat']}
    print(student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat']}
    

    深浅copy前面列表有介绍哦

    有想深入了解的同学可访问:https://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html

    fromkeys()方法

    • 功能: fromkeys() 函数用于创建一个新字典,以序列seq中元素做字典的键,value 为字典所有键对应的初始值。
    • 语法:
      • dict.fromkeys(seq[, value])
        • seq表示 字典键值列表
        • value -- 可选参数, 设置键序列(seq)的值,一般为None
    • 返回值: 该方法返回一个新字典

    案例:创建一个新字典,内容的key为学生消息,值为None

    res2 = {}.fromkeys(["name", 'age'], None)
    res3 = {}.fromkeys(["name", 'age'], [])
    print(res2)  # {'name': None, 'age': None}
    print(res3)  # {'name': [], 'age': []}
    print(res2['name'])  # None
    print(res3['name'])  # []
    

    需要注意的是:如果你将value初始值为一个列表,后面根据key改value会将整个字典全部的key对应的初始列表改变

    has_key()方法(了解)

    • 注意:Python 3.X 不支持该方法

    • 功能: 判断键是否存在于字典中,如果键在字典 dict 里返回 true,否则返回 false

    • 语法:

      • dict.has_key(key)
        • key -- 要在字典中查找的键
    • 返回一个布尔值

    案例:判断学生字典中的是否有name这个键

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    print(student_dict.has_key("name"))  # True
    

    setdefault()方法

    • 功能: get()方法 类似, 如果键不存在于字典中,将会添加键并将值设为默认值
    • 语法:
      • dict.setdefault(key, default=None)
        • key 查找的键值
        • default -- 键不存在时,设置的默认键值
    • 返回值: 如果字典中包含有给定键,则返回该键对应的值,否则返回为该键设置的值

    案例:判断学生字典中是否有性别(sex)的key,没有就添加,有就不动

    student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
    
    # key不存在则添加key:value,key如果存在则什么都不做
    # if "sex" not in student_dict:
    #     student_dict['sex'] = "male"
    
    student_dict.setdefault("sex", "male")  # 等用于上方的操作
    print(student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat'], 'sex': 'male'}
    

    update()方法

    • 功能: 把字典dict2的键/值对更新到dict里
    • 语法:
      • dict.update(dict2)
    • 返回值: 该方法没有任何返回值

    案例:将水果字典添加到学生字典中

    student_dict = {'name': 'jkey', 'age': 18}
    goads_dict = {'apple': 2, 'pear': 3, 'peach': 5, 'name': 'liu'}
    student_dict.update(goads_dict)  # 将goads_dict的键值对添加到student_dict字典中,没有的键会将键值对直接添加在student_dict最后,如果student_dict字典中有
    # 这个key-键 则会根据key-键 更新掉字典中的value
    print(student_dict)  # ==> {'name': 'liu', 'age': 18, 'apple': 2, 'pear': 3, 'peach': 5}
    

    函数

    序号 函数及描述
    1 cmp(dict1, dict2) 比较两个字典元素。
    2 len(dict)计算字典元素个数,即键的总数。
    3 str(dict) 输出字典可打印的字符串表示。
    4 type(variable) 返回输入的变量类型,如果变量

    cmp()方法(了解)

    • 在python2所有版本中都可用,但在python3中该函数已经被删掉。

    • 功能:用于比较两个字典元素。

    • 方法语法:cmp(dict1, dict2)

      • dict1 -- 比较的字典
      • dict2 -- 比较的字典

    返回值:如果两个字典的元素相同返回0,如果字典dict1大于字典dict2返回1,如果字典dict1小于字典dict2返回-1。

    案例:比较字典1和字典2元素大小

    dict1 = {'name': 'jkey', 'age': 18}
    dict2 = {'name': 'liu', 'age': 22}
    print(cmp(dict1,dict2))
    

    len()方法

    • 功能: 计算字典元素个数,即键的总数
    • 语法:
      • len(dict)
        • dict -- 要计算元素个数的字典
    • 返回值: 返回字典的元素个数

    案例:打印出学生字典中的键的个数

    student_dict = {'name': 'jkey', 'age': 18}
    print(len(student_dict))  # ===> 2
    

    str()方法

    • 功能: 将值转化为适于人阅读的形式,以可打印的字符串表示。
    • 语法:
      • str(dict)
    • 返回值: 返回字符串

    案例:将学生字典的键值对转换成字符串描述

    student_dict = {'name': 'jkey', 'age': 18}
    print(str(student_dict))  # ====> {'name': 'jkey', 'age': 18}
    

    type()方法

    • 功能: 返回输入的变量类型,如果变量是字典就返回字典类型。
    • 语法:
      • type(dict)
    • 返回的是一个数据类型

    案例:判断student_dict的数据类型

    student_dict = {'name': 'jkey', 'age': 18}
    print(type(student_dict))  # ===> <class 'dict'>
    

    好啦,大概就这么多了,字典在之后的用处还是很多的,因为我们都知道我们要做的就是对数据的一些存取,字典不仅仅可以存多个值还方便通过key去取值,加油吧!!!!!骚年!!!!

  • 相关阅读:
    asyncio异步 loop.run_in_executor操作同步方法变成异步操作
    pandas水平拆分dataframe
    vscode 运行python程序设置参数
    dbeaver 连接oracle11g 驱动问题
    python3 使用数据描述器,验证字段类型
    postgres 列转行操作记录
    python3 读取照片写入数据库postgres
    个人作业——软件工程实践总结作业
    2019 SDN上机第7次作业
    2019 SDN上机第6次作业
  • 原文地址:https://www.cnblogs.com/jkeykey/p/14180995.html
Copyright © 2020-2023  润新知