python内置对象类型(四)序列之dict字典,深拷贝与浅拷贝辨析

字典的相关定义

Python 字典是一种无序的、可变的序列,元素以“键值对(key-value)”形式存储
而列表(list)和元组(tuple)都是有序的序列(这里的有序不是说他们的元素大小是有序排列的的,而是说它们的元素在内存是连续挨着存放的,通常将索引值为0的元素称为第一个元素。)

字典类型是 Python 中唯一的映射类型

在这里插入图片描述

一、字典的创建

键必须不同,但是不同的键的值可以一样
键只能是整数、字符串或者元组这些唯一和不可变的类型,因此列表不能做键
值可以是 Python 支持的任意数据类型和自定义类型。

需要注意的是字典里面没有要求所有的key或者所有的value 的类型都一样,即不要求所有的键的类型都一样,也不要求所有val的值都一样,这一点和列表、元组一样,即不要求所存的数据的类型一致(是个筐 什么都能装)

键或者值是字符串/字符时需要有引号(单双都可以)

方法一、使用 { } 创建字典
键和值之间使用冒号:分隔,相邻元素之间使用逗号,分隔,所有元素放在大括号{ }中

#使用字符串作为key
scores = {'数学': 95, '英语': 92, '语文': 84}
print(scores)

使用元组和数字作为key  两个key的类型分别是元组和数字 val分别是字符串和列表
dict1 = {(20, 30): 'great', 30: [1,2,3]}
print(dict1)

#创建空元组
dict2 = {}
print(dict2)

运行结果
{'数学': 95, '英语': 92, '语文': 84}
{(20, 30): 'great', 30: [1, 2, 3]}
{}

方法二、 内置函数dict()创建
通过dict()函数创建字典的写法可以如下
在这里插入图片描述
zip创建传入的参数实质是一个 zip object of two-element-tuple
zip传送门:https://blog.csdn.net/Wjf7496/article/details/109597053

方法三、 dict 字典类型提供的 fromkeys() 方法创建带有默认值的字典
具体格式为:
dictname = dict.fromkeys(list,value=None)
list 参数表示字典中所有键的列表(list)
value 参数表示默认值,如果不写则为空值 None

knowledge = ['语文', '数学', '英语']
scores = dict.fromkeys(knowledge, 60)
print(scores)

运行结果
{'语文': 60, '英语': 60, '数学': 60}
该方法通常用于字典的初始化

二、字典的访问

方法一、通过键访问 :dictname[key]
访问时键必须是存在的否则会抛出异常,程序终止

列表和元组是通过下标来访问元素,而字典通过键来访问对应的值,因为字典中的元素是无序的,每个元素的位置都不固定,所以字典也不能像列表和元组那样,采用切片的方式一次性访问多个元素

方法二、通过dict的get(key)方法访问(推荐):dictname.get(key[,default])
当指定的键不存在时不会抛出异常
dictname 表示字典变量的名字;key 表示指定的键;default 用于指定要查询的键不存在时,此方法返回的默认值,如果不手动指定,会返回 None,如果想明确地提示该键不存在,那么可以手动设置 get() 的第二个参数

get(key)方法返回对应key 的值 当key不存在返回系统默认的None或者我们自己指定的第二个参数get不会修改原字典

a = dict(two=0.65, one=88, three=100, four=-59)
print( a.get('one') )
print( a.get('five', '该键不存在') )
del(a);
运行结果
88
该键不存在

区分dict的setdefault(key[,default])方法 在key不存在时会修改原来的字典
若key存在返回其值
若key不存在且没有指定默认值在字典中插入<key,None>键值对
若key不存在且指定了默认值defaultValue在字典中插入<key,defaultValue>键值对

在这里插入图片描述
在这里插入图片描述

Python 自带垃圾回收功能,会自动销毁不用的字典,所以一般不需要通过 del 来删除

三、字典的基本操作

字典是可变序列 因此可以:
1、dictname[key] = value:向现有字典中添加新的键值对,key必须在现有键中不存在
也可以使用字典提供的update()方法

2、修改现有字典中的键值对,这里指的是修改值(value)键不可修改
字典中各元素的键必须是唯一的,因此,如果新添加元素的键与已存在元素的键相同,那么键所对应的值就会被新的值替换掉,以此达到修改元素值的目的
也可以使用字典提供的pop(key)方法

a = {'数学': 95, '语文': 89, '英语': 90}
print(a)
a['语文'] = 100
print(a)

3、del dictName[key] 删除字典中键为key的键值对

4、key in dicName 检查某个键key是否在字典中 注意只能检查key是否存在 不能检查val,判断现有字典中是否存在指定的键值对。

5、len(dicName) 求字典中键值对的个数

四、字典的常用方法

在这里插入图片描述

1、get(key[,default]):获取key的val或默认值
2、setdefault(key[,default]):获取key的val或添加默认键值对

3、update():增加键值对
如果被更新的字典中己包含对应的键值对,那么原 value 会被覆盖
如果被更新的字典中不包含对应的键值对,则该键值对被添加进去

传入的参数可以是一个字典;也可以是一个元组或列表,而它们中的元素又是只包含两个元素的元组或列表,这和通过dict创建列表是一致的

a = {'one': 1, 'two': 2, 'three': 3}
a.update({'one':4.5, 'four': 9.3})
print(a)
a.update([('course','语文'),('name','Eniac'),(10,'me')]);
print(a)

运行结果
{'one': 4.5, 'two': 2, 'three': 3, 'four': 9.3}  修改one 添加four
{'one': 4.5, 'two': 2, 'three': 3, 'four': 9.3, 
 'course': 'english', 'name': 'Eniac', 10: 1}  
传入列表 列表元素是元组 各个元组的元素类型(key和val)不一样

4、pop(key[,d]):删除键值对
若key存在,删除键值对并返回该key对应的val
若key不存在且给出了参数d 返回d
若key不存在且没有给出了参数d程序异常终止KeyError
在这里插入图片描述5、popitem() 删除字典最后一对键值对并返回该键值对 若字典为空异常终止KeyError
该方法在python3.6以后适用,之前是随机删除一对键值对,需要注意的是即使如此字典也不是有序的,这里所指的最后一个是指字典创建时键值对添加进字典的顺序(即存储键值对的底层数据结构的最后一个)

6、获取字典中的特定数据的三个方法:
keys() 方法用于返回字典中的所有键(key)
values() 方法用于返回字典中所有键对应的值(value)
items() 用于返回字典中所有的键值对(key-value)

7、copy() :返回一个字典的拷贝,也即返回一个具有相同键值对的新字典,
copy() 方法所遵循的拷贝原理既有深拷贝,也有浅拷贝。
拿拷贝字典 a 为例,copy() 方法只会对最表层的键值对进行深拷贝,也就是说,它会再申请一块内存用来存放 {‘one’: 1, ‘two’: 2, ‘three’: []};而对于某些列表类型(可变类型)的值来说,此方法对其做的是浅拷贝,也就是说,b 中的 [1,2,3] 的值不是自己独有,而是和 a 共有

a = {'one': 1, 'two': 2, 'three': [1,2,3]}
b = a.copy()
向 a 中添加新键值对,由于b已经提前将 a 所有键值对都深拷贝过来,因此 a 添加新键值对,不会影响b。
a['four']=100
print(a)
print(b)

由于 b 和 a 共享[1,2,3](浅拷贝),因此移除 a 中列表中的元素,也会影响 b。
这里键three是一个列表,remove(val)删除列表中特定值为val的元素 区分列表的pop(index)删除
a['three'].remove(1)  
print(a)
print(b)

运行结果
{'one': 1, 'two': 2, 'three': [1, 2, 3], 'four': 100}
{'one': 1, 'two': 2, 'three': [1, 2, 3]}    b没变
{'one': 1, 'two': 2, 'three': [2, 3], 'four': 100}  a b都变了
{'one': 1, 'two': 2, 'three': [2, 3]}

注意 列表、字典、集合的copy()都是浅拷贝:最外层深拷贝,其余浅拷贝
另外元组tuple根本没有copy()这个方法

以list为例
lst和lst1的内存地址不一样,说明是两个不同的对象id() 或者is两种方法 id不同 内存不同 is返回false

但是 lst == lst1返回true ==判断是否相等
is id判断是否是同一个对象(内存)

但是lst[0]和lst1[0]、lst[3]和lst1[3](最外层列表)是同一个
相当于列表lst 筐换了,但是筐里面的元素没换
在这里插入图片描述
修改最外层元素 互不影响
在这里插入图片描述
修改内层元素元素 相互同步
lst[3][0]和lst1[3][0]也是同一个
在这里插入图片描述

要实现深拷贝需要import.copy模块 调用copy.deepcopy()
内层、外层修改都互不影响 筐和元素都不是同一个
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值