7.6 数据结构之字典
7.6 数据结构之字典
- 用于存放具有映射关系的数据。
- 字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合,程序需要通过Key来访问Value,因此在同一个字典中,键(key)必须是唯一的。

1 创建格式:
dict1 = {key01 : value01, key02 : value02, …}
2 常用功能
# 空dict
empty_dict1 = {}
empty_dict2 = dict()
print(empty_dict1)
# 输出:{}
print(empty_dict2)
# 输出:{}
dict1 = {'语文': 80, '数学': 70, '英语': 60}
#访问
# 通过 key 访问 value 使用的也是方括号语法,就像前面介绍的列表和元组一样,只是此时在方括号中放的是 key,而不是列表或元组中的索引。
print(dict1)
# 输出:{'语文': 80, '数学': 70, '英语': 60}
print(dict1.keys())
# 输出:dict_keys(['语文', '数学', '英语'])
print(dict1.values())
# 输出:dict_values([80, 70, 60])
print(dict1['数学'])
# 输出:70
# 通过 key 添加 key-value 对。
dict1['日语'] = 89
print(dict1)
# 输出:{'语文': 80, '数学': 70, '英语': 60, '日语': 89}
# 通过 key 删除 key-value 对。
del dict1['数学']
print(dict1)
# 输出:{'语文': 80, '英语': 60, '日语': 89}
# 通过 key 修改 key-value 对。
dict1['语文'] = 99
print(dict1)
# 输出:{'语文': 99, '英语': 60, '日语': 89}
# 通过 key 判断指定 key-value 对是否存在。
print('日语' in dict1)
print('日语' not in dict1)
# 输出:True
# 输出:False
# 使用dict()函数创建字典
dict2 = [('语文', 100), ('数学', 90), ('英语', 80)]
dict3 = dict(dict2)
print(dict3)
# 输出:{'语文': 100, '数学': 90, '英语': 80}
dict4 = dict(语文=80, 数学=70, 英语=60)
print(dict4)
# 输出:{'语文': 80, '数学': 70, '英语': 60}
3 字典的常用方法
字典由 dict 类代表,可以使用dir()查看该类包含哪些方法
[‘clear’, ‘copy’, ‘fromkeys’, ‘get’, ‘items’, ‘keys’, ‘pop’, ‘popitem’, ‘setdefault’, ‘update’, ‘values’]
# clear:删除字典内所有元素
dict1.clear()
print(dict1)
# 输出:{}
# 浅copy
dict1 = dict3.copy()
print(dict1)
# 输出:{'语文': 100, '数学': 90, '英语': 80}
# fromkeys:创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值。
dict5 = dict.fromkeys(dict1)
print(dict5)
# 输出:{'语文': None, '数学': None, '英语': None}
dict5 = dict.fromkeys(dict1, 10)
print(dict5)
# 输出:{'语文': 10, '数学': 10, '英语': 10}
# get:返回指定键的值,如果值不在字典中返回default值
print(dict1.get('语文'))
# 输出:100
print(dict1.get('美术'))
# 输出:None
print(dict1)
# items:以列表返回可遍历的(键, 值) 元组数组
print(dict1.items())
# 输出:dict_items([('语文', 100), ('数学', 90), ('英语', 80)])
# keys:以列表返回一个字典所有的键
print(dict1.keys())
# 输出:dict_keys(['语文', '数学', '英语'])
# pop:删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
dict1.pop('语文')
print(dict1)
# 输出:{'数学': 90, '英语': 80}
# popitem: 返回并删除字典中的最后一对键和值。
dict1.popitem()
print(dict1)
# 输出:{'数学': 90}
# setdefault:和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
dict1.setdefault('数学')
print(dict1)
# 输出:{'数学': 90}
dict1.setdefault('日语')
print(dict1)
# 输出:{'数学': 90, '日语': None}
# update:把字典dict3的键/值对更新到dict1里
dict1.update(dict3)
print(dict1)
# 输出:{'数学': 90, '日语': None, '语文': 100, '英语': 80}
# values:以列表返回字典中的所有值
print(dict1.values())
# 输出:dict_values([90, None, 100, 80])
# 多级字典嵌套
catalog = {
"广东":{
"广州": ["广州1","广州2"],
"深圳": ["深圳1","深圳2"],
"东莞": ["东莞1","东莞2"],
},
"福建":{
"厦门":["厦门1","厦门2"]
},
"安徽":{
"合肥":["合肥1","合肥2"]
}
}
catalog["福建"]["厦门"][1] += ",真好玩!"
print(catalog["福建"]["厦门"])
# 输出:['厦门1', '厦门2,真好玩!']
4 字典遍历
>>> dict1 = {'语文': 80, '数学': 70, '英语': 60, '日语': 89}
>>> print(dict1.items())
dict_items([('语文', 80), ('数学', 70), ('英语', 60), ('日语', 89)])
>>> print(dict1.keys())
dict_keys(['语文', '数学', '英语', '日语'])
>>> print(dict1.values())
dict_values([80, 70, 60, 89])
通过输出结果可以看到:访问字典时,是通过列表表示的,每个key与value对是通过列表中的元组进行表示;
4.1 直接遍历,值为Key
>>> for key in dict1:
... print(key, dict1[key])
...
语文 80
数学 70
英语 60
日语 89
>>>
4.2 通过key遍历
>>> for key in dict1.keys():
... print(key, dict1[key])
...
语文 80
数学 70
英语 60
日语 89
>>>
4.3 value遍历
>>> for value in dict1.values():
... print(value)
...
80
70
60
89
>>>
4.4 枚举遍历
>>> for key, value in enumerate(dict1):
... print(key, value)
...
0 语文
1 数学
2 英语
3 日语
>>>
4.5 item遍历:
#会先把dict转成list,数据里大时莫用
>>> for item in dict1.items():
... print(item)
...
('语文', 80)
('数学', 70)
('英语', 60)
('日语', 89)
>>>
>>> for key, value in dict1.items():
... print(key, value)
...
语文 80
数学 70
英语 60
日语 89
>>>
- 上面所说到的遍历方式非常占用内存,使用迭代器,大大减少内存的使用。
4.6 字典迭代器
>>> for key in iter(dict1):
... print(key)
...
语文
数学
英语
日语
>>> for key in iter(dict1):
... print(key, dict1[key])
...
语文 80
数学 70
英语 60
日语 89
>>>
5 字典排序
5.1 依据字典中的 value 值,对字典进行有序排序
from collections import OrderedDict
test_dict = {1: 5, 2: 4}
keys = sorted(test_dict, key=lambda x: x, reverse=True)
order_dict = OrderedDict()
for key in keys:
order_dict[key] = test_dict[key]
print('order_dict>>: ', order_dict)
5.2 依据字典中的 value 值,对字典进行有序排序
from collections import OrderedDict
test_dict = {1: 5, 2: 4}
sort_dict = sorted(test_dict, key=lambda x: test_dict[x], reverse=True)
print(sort_dict)
# 排序案例
data = {
'privilege__url': '/customer/list/',
'privilege__title': '客户展示',
'privilege__menu__id': 1,
'privilege__menu__title': '客户信息',
'privilege__menu__icon': 'fa fa-users fa-spin',
'privilege__menu__weight': 90
}, {
'privilege__url': '/payment/list/',
'privilege__title': '缴费展示',
'privilege__menu__id': 2,
'privilege__menu__title': '小钱钱',
'privilege__menu__icon': 'fa fa-rmb fa-spin',
'privilege__menu__weight': 100
}, {
'privilege__url': '/taxes/',
'privilege__title': '缴税展示',
'privilege__menu__id': 2,
'privilege__menu__title': '小钱钱',
'privilege__menu__icon': 'fa fa-rmb fa-spin',
'privilege__menu__weight': 100
}, {
'privilege__url': '/customer/edit/(?P<cid>\\d+)/',
'privilege__title': '编辑客户',
'privilege__menu__id': None,
'privilege__menu__title': None,
'privilege__menu__icon': None,
'privilege__menu__weight': None
}, {
'privilege__url': '/customer/del/(?P<cid>\\d+)/',
'privilege__title': '删除客户',
'privilege__menu__id': None,
'privilege__menu__title': None,
'privilege__menu__icon': None,
'privilege__menu__weight': None
}
menu_dict = {}
for i in data:
if i.get('privilege__menu__id'):
if i.get('privilege__menu__id') in menu_dict:
menu_dict[i.get('privilege__menu__id')]['sec_menu'].append({
'title': i.get('privilege__title'),
'url': i.get('privilege__url'),
})
else:
menu_dict[i.get('privilege__menu__id')] = {
'title': i.get('privilege__menu__title'),
'icon': i.get('privilege__menu__icon'),
'weight': i.get('privilege__menu__weight'),
'sec_menu': [{
'title': i.get('privilege__title'),
'url': i.get('privilege__url'),
}],
}
print(menu_dict)
keys = sorted(menu_dict, key=lambda x: menu_dict[x]['weight'],reverse=True)
d1 = OrderedDict()
for key in keys:
d1[key] = menu_dict[key]
menu_dict = d1
print(menu_dict)
6 其他知识
- 字典查询速度远大于列表的原因:
dict会把所有的key变成hash 表,然后将这个表进行排序,即彩虹表。
通过data[key]去查data字典中一个key的时候,python会先将key 做hash得到一个hash值,将该hash值到hash表中进行对比查找,若存在,通过hash值索引,到与此key对应的value的内存地址那取值。
查询速度快,比列表快多了