字典是一系列由键(key)和值(value)配对组成的元素的集合,在 Python3.7+,字典被确定为有序(注意:在 3.6 中,字典有序是一个implementation detail,在 3.7 才正式成为语言特性,因此 3.6 中无法 100% 确保其有序性),而 3.6 之前是无序的,其长度大小可变,元素可以任意地删减和改变。
直接初始化
>>> a = {'age' : 1}
1.dict() 构造函数可以直接从键值对序列里创建字典
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
2.字典推导式可以从任意的键值表达式中创建字典
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
3.当关键字是简单字符串时,有时直接通过关键字参数来指定键值对更方便
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
把数据放入dict的方法,除了初始化时指定外,还可以通过key直接放入:
>>> d = {}
>>> d['Adam'] = 67
>>> d['Adam']
67
要删除一个key,用pop(key)方法(该函数返回值为key对应的value值),对应的value也会从dict中删除。
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}
也可以用del 来删除一个键值对。
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> del d['Bob']
>>> d
{'Michael': 95, 'Tracy': 85}
可以通过key获取其value直接对其进行赋值
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Bob'] = 70
>>> d
{'Michael': 95, 'Bob': 70, 'Tracy': 85}
另外可以通过update函数来对字典的value进行修改
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d.update(Bob=70)
>>> d
{'Michael': 95, 'Bob': 70, 'Tracy': 85}
注意:update函数,对于不存在的key会添加该key.
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d.update(sex='N')
>>> d
{'Michael': 95, 'Bob': 70, 'Tracy': 85, 'sex': 'N'}
直接通过访问索引键来访问
>>> d = {'name': 'jason', 'age': 20}
>>> d['name']
'jason'
>>>
查询时若key不存在:直接通过d[‘Thomas’]这种方式去获取该key对应的value会报错,要避免key不存在的错误,有两种办法,
>>> 'Thomas' in d
False
>>> d.get('Thomas')
>>> d.get('Thomas', -1) # 如果Thomas不存在,返回-1
-1
注意:返回None的时候Python的交互环境不显示结果
查询key,value
dic = {'name': 'chen', 'age': 25, 'loc': 'Tianjin'}
# 字典的keys()、values()方法的返回值是view odject对象,是iterable可迭代对象
# 以列表的形式返回key
list(dic.keys())
# 以列表的形式返回value
list(dic.values())
# 循环key
for key in dic:
print(key)
# 循环key
for key in dic.keys():
print(key)
# 循环value,用value()方法可以将所有value取出
for value in dic.values():
print(value)
# 当在字典中循环时,用items() 方法可将关键字和对应的值同时取出
# items() 方法的遍历:items() 方法把字典中每对 key 和 value 组成一个元组,并把这些元组放在列表中返回。
d = {'one': 1, 'two': 2, 'three': 3}
>>> d.items()
dict_items([('one', 1), ('two', 2), ('three', 3)])
>>> type(d.items())
<class 'dict_items'>
>>> for key,value in d.items():#当两个参数时
print(key + ':' + str(value))
one:1
two:2
three:3
>>> for i in d.items():#当参数只有一个时
print(i)
('one', 1)
('two', 2)
('three', 3)
在 Python3.7+,字典被确定为有序(注意:在 3.6 中,字典有序是一个implementation detail,在 3.7 才正式成为语言特性,因此 3.6 中无法 100% 确保其有序性),而 3.6 之前是无序的,其长度大小可变,元素可以任意地删减和改变。
对于无序dict的迭代需要注意的是:因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。(dict的标准规定不保证有顺序,要保证有顺序的请用OrderedDict)
from collections import OrderedDict
d = OrderedDict()
关于dict无序这个问题的探讨,可以看看下面这篇,如果想深究,建议看一下源码,博主在这个地方没深究过。
https://www.zhihu.com/question/65855807
在 Python3.7+,字典被确定为有序(注意:在 3.6 中,字典有序是一个implementation detail,在 3.7 才正式成为语言特性,因此 3.6 中无法 100% 确保其有序性),而 3.6 之前是无序的,其长度大小可变,元素可以任意地删减和改变。由于字典可能是无序的,因此任何对字典的排序问题,都要最终归结为对字典(dict)的键(key)或者值(value)组成的列表(list)的排序。
1.按字典(dict)的键进行排序
第一种方法:
def sortedDictValues(adict,reverse=False):
keys = adict.keys()
keys.sort(reverse=reverse)
return [adict[key] for key in keys] # 如果需要同时返回键和值的话则改为return [(key,adict[key]]) for key in keys]
第二种方法:使用内置的sorted()方法进行排序,不过性能会有些许的下降,如果很苛求性能,还是使用原生对list.sort()方法比较好
>>> d = {'c':1,'e':'5','b':7}
>>> sorted(d.items())
[('b', 7), ('c', 1), ('e', '5')]
2.按字典(dict)的键进行排序
第一种方法:
def sorted_dict(container, keys, reverse):
"""返回 keys 的列表,根据container中对应的值排序"""
aux = [ (container[k], k) for k in keys]
aux.sort()
if reverse: aux.reverse()
return [k for v, k in aux]
第二种方法:
sorted(d.items(), key=lambda d:d[1])
需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。如果一个元组只包含字符串、数字或元组,那么这个元组也可以用作关键字。但如果元组直接或间接地包含了可变对象,那么它就不能用作关键字。列表不能用作关键字,因为列表可以通过索引、切片或append() 和extend() 之类的方法来改变。
关于初始化的问题
下面初始化字典的方式,哪一种更高效
# Option A
d = {'name': 'jason', 'age': 20, 'gender': 'male'}
# Option B
d = dict({'name': 'jason', 'age': 20, 'gender': 'male'})
利用timeit命令查看二者花费的时间,关于timeit的用法可以参考:https://blog.csdn.net/CHCH998/article/details/106867831
很明显可以看出来,第一种利用{}的初始化的方法更快。
C:\Users\shdst>python -m timeit dict({'name': 'jason', 'age': 20, 'gender': 'male'})
1000000 loops, best of 5: 230 nsec per loop
C:\Users\shdst>python -m timeit {'name': 'jason', 'age': 20, 'gender': 'male'}
5000000 loops, best of 5: 75.9 nsec per loop
C:\Users\shdst>
通过分析其字节码比较二者哪个更快,python中的dis模块可以查看一句python代码的cpu运行轨迹,也就是cpu指令,很明显第一种方式所使用的cpu指令比第二种少LOAD_GLOBAL 与CALL_FUNCTION ,所以第一种更高效。关于字节码的分析可以参考这篇博文https://blog.csdn.net/qq_27283619/article/details/106021295,
官方的dis模块介绍为https://docs.python.org/3/library/dis.html
>>> import dis
>>> dis.dis(lambda: {'name': 'jason', 'age': 20, 'gender': 'male'})
1 0 LOAD_CONST 1 ('jason')
2 LOAD_CONST 2 (20)
4 LOAD_CONST 3 ('male')
6 LOAD_CONST 4 (('name', 'age', 'gender'))
8 BUILD_CONST_KEY_MAP 3
10 RETURN_VALUE
>>> dis.dis(lambda: dict({'name': 'jason', 'age': 20, 'gender': 'male'}))
1 0 LOAD_GLOBAL 0 (dict)
2 LOAD_CONST 1 ('jason')
4 LOAD_CONST 2 (20)
6 LOAD_CONST 3 ('male')
8 LOAD_CONST 4 (('name', 'age', 'gender'))
10 BUILD_CONST_KEY_MAP 3
12 CALL_FUNCTION 1
14 RETURN_VALUE
>>>
参考:
廖雪峰的python教程,以及官方文档,强烈建议有问题找官方文档。
我这里面有python3.8的中文官方文档可以自行获取https://download.csdn.net/download/qq_38048756/13096127。
Python 字典(Dictionary) items()方法 :https://www.runoob.com/python/att-dictionary-items.html
Python中字典(dict)和列表(list)的排序方法实例 https://www.jb51.net/article/51115.htm