字典(dict)
字典(dict)
定义
- 采用大括号**{}和dict()**创建,键值对用冒号: 表示;
- 可以存储任意类型对象
- 任何 Python 对象都可用作字典中的值;键可以是任何不可变的类型;
- **函数 dict()😗*从其他映射(如其他字典)或键值对序列创建字典
- 键-值对排列顺序与添加顺序不同
字典类型操作函数和方法
方法名称 | 功能 |
---|---|
del d[k] | 删除字典 d 中键 k 对应的数据值,永久删除 |
k in d | 判断键 k是否在字典 d 中,如果在返回 True,否则 False |
d.keys() | 返回字典 d 中所有的键信息 |
d.values() | 返回字典 d 中所有的值信息 |
d.items() | 返回字典 d 中所有的键值对信息 |
d.get(k, [default]) | 键 k 存在,则返回相应值,不在则返回[default]值 |
d.pop(k, [default]) | 键 k 存在,则取出相应值,不在则返回[default]值 |
d.popitem() | 随机从字典 d 中取出一个键值对,以元组形式返回 |
d.clear() | 删除所有的键值对 |
len(d) | 返回字典 d 中元素的个数 |
d.copy () | 返回与原字典相同的键值对的新字典 |
创建
1) 使用 { } 创建字典
由于字典中每个元素都包含两部分,分别是键(key)和值(value),因此在创建字典时,键和值之间使用冒号:
分隔,相邻元素之间使用逗号,
分隔,所有元素放在大括号{ }
中。
使用{ }
创建字典的语法格式如下:
dictname = {'key':'value1', 'key2':'value2', ..., 'keyn':valuen}
其中 dictname 表示字典变量名,keyn : valuen 表示各个元素的键值对。需要注意的是,同一字典中的各个键必须唯一,不能重复。
如下代码示范了使用花括号语法创建字典:
#使用字符串作为key
scores = {'数学': 95, '英语': 92, '语文': 84}
print(scores)
#使用元组和数字作为key
dict1 = {(20, 30): 'great', 30: [1,2,3]}
print(dict1)
#创建空元组
dict2 = {}
print(dict2)
2
3
4
5
6
7
8
9
{'数学': 95, '英语': 92, '语文': 84} {(20, 30): 'great', 30: [1, 2, 3]} {}
字典的键可以是整数、字符串或者元组,只要符合唯一和不可变的特性就行;字典的值可以是 Python 支持的任意数据类型。
2) 通过 fromkeys() 方法创建字典
Python 中,还可以使用 dict 字典类型提供的 fromkeys() 方法创建带有默认值的字典,具体格式为:
dictname = dict.fromkeys(list,value=None)
其中,list 参数表示字典中所有键的列表(list);value 参数表示默认值,如果不写,则为空值 None。
knowledge = ['语文', '数学', '英语']
scores = dict.fromkeys(knowledge, 60)
print(scores)
2
3
运行结果为:
{'语文': 60, '英语': 60, '数学': 60}
可以看到,knowledge 列表中的元素全部作为了 scores 字典的键,而各个键对应的值都是 60。这种创建方式通常用于初始化字典,设置 value 的默认值。
3) 通过 dict() 映射函数创建字典
通过 dict() 函数创建字典的写法有多种,表 2 罗列出了常用的几种方式,它们创建的都是同一个字典 a。
创建格式 | 注意事项 |
---|---|
a = dict(str1=value1, str2=value2, str3=value3) | str 表示字符串类型的键,value 表示键对应的值。使用此方式创建字典时,字符串不能带引号。 |
#方式 1 demo = [('two',2), ('one',1), ('three',3)] #方式 2 demo = [['two',2], ['one',1], ['three',3]] #方式 3 demo = (('two',2), ('one',1), ('three',3)) #方式 4 demo = (['two',2], ['one',1], ['three',3]) a = dict(demo) | 向 dict() 函数传入列表或元组,而它们中的元素又各自是包含 2 个元素的列表或元组,其中第一个元素作为键,第二个元素作为值。 |
keys = ['one', 'two', 'three'] #还可以是字符串或元组 values = [1, 2, 3] #还可以是字符串或元组 a = dict( zip(keys, values) ) | 通过应用 dict() 函数和 zip() 函数,可将前两个列表转换为对应的字典。 |
注意,无论采用以上哪种方式创建字典,字典中各元素的键都只能是字符串、元组或数字,不能是列表。列表是可变的,不能作为键。
遍历字典
scores = {'数学': 95, '语文': 89, '英语': 90}
print(scores.keys())
print(scores.values())
print(scores.items())
2
3
4
dict_keys(['数学', '语文', '英语']) dict_values([95, 89, 90]) dict_items([('数学', 95), ('语文', 89), ('英语', 90)])
可以发现,keys()、values() 和 items() 返回值的类型分别为 dict_keys、dict_values 和 dict_items。
需要注意的是,在 Python 2.x 中,上面三个方法的返回值都是列表(list)类型。但在 Python 3.x 中,它们的返回值并不是我们常见的列表或者元组类型,因为 Python 3.x 不希望用户直接操作这几个方法的返回值。
在 Python 3.x 中如果想使用这三个方法返回的数据,一般有下面两种方案:
使用 list() 函数,将它们返回的数据转换成列表,例如:
a = {'数学': 95, '语文': 89, '英语': 90} b = list(a.keys()) print(b)
1
2
3for in 循环
for key, value in 字典名.items():(key, value 名称任意);遍历字典时,键值对遍历顺序与存储顺序也不同。
for key in 字典名.keys():(key 名称任意)遍历字典中所有键;遍历字典时,会默认遍历所有键。
for key in sorted(字典名.keys()):(key 名称任意)按顺序遍历字典中所有键;字母顺序排序。
遍历字典中所有值**:for value in 字典名.values():(value 名称任意);为避免重复项,调用for value in set(字典名.values())**:(value 名称任意);
a = {'数学': 95, '语文': 89, '英语': 90} for k in a.keys(): print(k,end=' ') print("\n---------------") for v in a.values(): print(v,end=' ') print("\n---------------") for k,v in a.items():
1
2
3
4
5
6
7
8数学 语文 英语 --------------- 95 89 90 --------------- key: 数学 value: 95 key: 语文 value: 89 key: 英语 value: 90
copy() 方法
copy() 方法返回一个字典的拷贝,也即返回一个具有相同键值对的新字典,例如:
a = {'one': 1, 'two': 2, 'three': [1,2,3]}b = a.copy()print(b)
运行结果为:
{'one': 1, 'two': 2, 'three': [1, 2, 3]}
可以看到,copy() 方法将字典 a 的数据全部拷贝给了字典 b。
注意,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。
a['three'].remove(1)
print(a)
print(b)
2
3
4
5
6
7
8
9
10
{'one': 1, 'two': 2, 'three': [1, 2, 3], 'four': 100}
{'one': 1, 'two': 2, 'three': [1, 2, 3]}
{'one': 1, 'two': 2, 'three': [2, 3], 'four': 100}
{'one': 1, 'two': 2, 'three': [2, 3]}
2
3
4
从运行结果不难看出,对 a 增加新键值对,b 不变;而修改 a 某键值对中列表内的元素,b 也会相应改变。
update() 方法
update() 方法可以使用一个字典所包含的键值对来更新己有的字典。
在执行 update() 方法时,如果被更新的字典中己包含对应的键值对,那么原 value 会被覆盖;如果被更新的字典中不包含对应的键值对,则该键值对被添加进去。
请看下面的代码:
a = {'one': 1, 'two': 2, 'three': 3}
a.update({'one':4.5, 'four': 9.3})
print(a)
2
3
运行结果为:
{'one': 4.5, 'two': 2, 'three': 3, 'four': 9.3}
从运行结果可以看出,由于被更新的字典中已包含 key 为“one”的键值对,因此更新时该键值对的 value 将被改写;而被更新的字典中不包含 key 为“four”的键值对,所以更新时会为原字典增加一个新的键值对。
pop() 和 popitem() 方法
pop() 和 popitem() 都用来删除字典中的键值对,不同的是,pop() 用来删除指定的键值对,而 popitem() 用来随机删除一个键值对,它们的语法格式如下:
dictname.pop(key)
dictname.popitem()
2
其中,dictname 表示字典名称,key 表示键。
下面的代码演示了两个函数的用法:
a = {'数学': 95, '语文': 89, '英语': 90, '化学': 83, '生物': 98, '物理': 89}
print(a)
a.pop('化学')
print(a)
a.popitem()
print(a)
2
3
4
5
6
运行结果:
{'数学': 95, '语文': 89, '英语': 90, '化学': 83, '生物': 98, '物理': 89}
{'数学': 95, '语文': 89, '英语': 90, '生物': 98, '物理': 89}
{'数学': 95, '语文': 89, '英语': 90, '生物': 98}
2
3
对 popitem() 的说明
其实,说 popitem() 随机删除字典中的一个键值对是不准确的,虽然字典是一种无序的列表,但键值对在底层也是有存储顺序的,popitem() 总是弹出底层中的最后一个 key-value,这和列表的 pop() 方法类似,都实现了数据结构 (opens new window)中“出栈”的操作。
setdefault() 方法
setdefault() 方法用来返回某个 key 对应的 value,其语法格式如下:
dictname.setdefault(key, defaultvalue)
说明,dictname 表示字典名称,key 表示键,defaultvalue 表示默认值(可以不写,不写的话是 None)。
当指定的 key 不存在时,setdefault() 会先为这个不存在的 key 设置一个默认的 defaultvalue,然后再返回 defaultvalue。
也就是说,setdefault() 方法总能返回指定 key 对应的 value:
- 如果该 key 存在,那么直接返回该 key 对应的 value;
- 如果该 key 不存在,那么先为该 key 设置默认的 defaultvalue,然后再返回该 key 对应的 defaultvalue。
请看下面的代码:
a = {'数学': 95, '语文': 89, '英语': 90}
print(a)
#key不存在,指定默认值
a.setdefault('物理', 94)
print(a)
#key不存在,不指定默认值
a.setdefault('化学')
print(a)
#key存在,指定默认值
a.setdefault('数学', 100)
print(a)
2
3
4
5
6
7
8
9
10
11
运行结果为:
{'数学': 95, '语文': 89, '英语': 90}
{'数学': 95, '语文': 89, '英语': 90, '物理': 94}
{'数学': 95, '语文': 89, '英语': 90, '物理': 94, '化学': None}
{'数学': 95, '语文': 89, '英语': 90, '物理': 94, '化学': None}
2
3
4
字典和 list
dict:
- 查找和插入的速度极快,不会随着 key 的增加而变慢;
- 需要占用大量的内存,内存浪费多。
list:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。