当前位置: 首页 > 工具软件 > dict_build > 使用案例 >

python之dict字典

云瑞
2023-12-01

字典是一系列由键(key)和值(value)配对组成的元素的集合,在 Python3.7+,字典被确定为有序(注意:在 3.6 中,字典有序是一个implementation detail,在 3.7 才正式成为语言特性,因此 3.6 中无法 100% 确保其有序性),而 3.6 之前是无序的,其长度大小可变,元素可以任意地删减和改变。

1.dict的增删改查及初始化

1.1 dict的初始化

直接初始化

>>> 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}

1.2 dict的“增”

把数据放入dict的方法,除了初始化时指定外,还可以通过key直接放入:

>>> d = {}
>>> d['Adam'] = 67
>>> d['Adam']
67

1.3 dict的“删”

要删除一个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}

1.4 dict的“改”

可以通过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'}

1.5 dict的“查”

直接通过访问索引键来访问

>>> d = {'name': 'jason', 'age': 20}
>>> d['name']
'jason'
>>>

查询时若key不存在:直接通过d[‘Thomas’]这种方式去获取该key对应的value会报错,要避免key不存在的错误,有两种办法,

  • 一是通过in判断key是否存在:
>>> 'Thomas' in d
False
  • 二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:
>>> 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)

2.dict的无序问题

在 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

3.排序问题

在 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])

4.其他

需要牢记的第一条就是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

 类似资料: