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的内存地址那取值。
    查询速度快,比列表快多了
posted @ 2020-05-16 22:29  f_carey  阅读(10)  评论(0编辑  收藏  举报  来源