字典

字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含:“键对象”和“值对象”。可以通过”键对象“实现快速获取、删除和更新对应的”值对象“。

列表中通过“下标数字”找到对应的对象。字典中通过键值对找到对应的值对象。“键”是任意的不可变数据,如:整数,浮点数,字符串,元组。但是列表、字典、集合这些是可变对象,不能作为“键”。并且“键”不可重复。

值可以使任何数据,并且可以重复。

典型的定义字典方式:

a = {'name':'shengtudai','age':18,'job':'student'}

字典的创建

1.通过{} 、dict()来创建字典对象

>>> b = dict(name='shengtudai',age=8,job='student')
>>> a = {'name':'shengtudai','age':18,'job':'student'}
>>> a = dict([('name','shengudai'),('age',18)])
>>> c = {}
>>> d = dict()

2.通过zip()创建字典对象

>>> k = ['name','age','job']
>>> v = ['shengtudai','18','student']
>>> d = dict(zip(k,v))
>>> d
{'name': 'shengtudai', 'age': '18', 'job': 'student'}

3.通过fromkeys创建值为空的字典

>>> a = dict.fromkeys(['name','age','job'])
>>> a
{'name': None, 'age': None, 'job': None}

字典元素的访问

设定一个字典对象

a = {'name':'shengtudai','age':18,'job':'student'}

1.通过键获得值。若键不存在,则抛出异常

>>> a['name']
'shengtudai'
>>> a['qq']
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    a['qq']
KeyError: 'qq'

2.通过get()方法获得‘值’。推荐使用,指定键不存在,则返回null

>>> a.get('name')
'shengtudai'
>>> a.get('qq')
>>> a.get('sex','一个男人')
'一个男人'

3.列出所有键值对

a.items()
dict_items([('name', 'shengtudai'), ('age', 18), ('job', 'student')])

4.列出所有的键,列出所有的值

>>> a.keys()
dict_keys(['name', 'age', 'job'])
>>> a.values()
dict_values(['shengtudai', 18, 'student'])

5.len()键值对的个数

>>> len(a)
3

6.检测一个“键”是否在字典中

>>> "name" in a
True

字典元素的添加、修改和删除

1.给字典新增键值对。如果键已经存在,则覆盖旧的键值对;若键不存在,则新增键值对

>>> a['address'] = '湖北公安'
>>> a['age'] = 16
>>> a
{'name': 'shengtudai', 'age': 16, 'job': 'student', 'address': '湖北公安'}

2.使用update()将新字典中所有键值对全部添加到旧字典上,如果key有重复,则直接覆盖

>>> a = {'name':'shengtudai','age':18,'job':'student'}
>>> b = {'name':'kugua','money':'1000','sex':'男的'}
>>> a.update(b)
>>> a
{'name': 'kugua', 'age': 18, 'job': 'student', 'money': '1000', 'sex': '男的'}

3.字典中元素的删除,可以使用del方法;或者clear()删除所有的键值对;pop()删除指定的键值对,并返回对应的"值对象"

>>> a = {'name':'shengtudai','age':18,'job':'student'}
>>> del(a["name"])
>>> a
{'age': 18, 'job': 'student'}
>>> b = a.pop('age')
>>> b
18

4.popitem():随机删除和返回该键值对。字典是“无序可变序列”,没有第一个和最后一个的概念;popitem()弹出随机的项

>>> a = {'name':'shengtudai','age':18,'job':'student'}
>>> a.popitem()
('job', 'student')
>>> a
{'name': 'shengtudai', 'age': 18}
>>> a.popitem()
('age', 18)
>>> a
{'name': 'shengtudai'}
>>> a.popitem()
('name', 'shengtudai')
>>> a
{}

序列解包

序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值

>>> x,y,z = (20,30,10)
>>> x
20
>>> y
30
>>> z
10
>>> type(x)
<class 'int'>
>>> (a,b,c) = (10,20,30)
>>> a
10
>>> (a,b,c) = [10,20,30]
>>> a
10

序列解包用于字典时,默认是对键进行操作;如果需要对键值对进行操作,则需要使用items();如果需要对值进行操作,则需要使用values()

>>> name,age,job = a
>>> name
'name'
>>> age
'age'
>>> job
'job'
>>> name,age,job = a.items()
>>> name
('name', 'shengtudai')
>>> name,age,job = a.values()
>>> name
'shengtudai'

表格数据使用字典和列表存储,并实现访问

r1 = {'name':'高小一','age':18,'salary':30000,'city':'北京'}
r2 = {'name':'高小二','age':19,'salary':20000,'city':'上海'}
r3 = {'name':'高小五','age':20,'salary':10000,'city':'深圳'}

tb = [r1,r2,r3]

#获得第二行的人的薪资
print(tb[1].get('salary'))

#打印列表中所有的薪资
for i in range(len(tb)):
    print(tb[i].get('salary'))
#打印表的所有数据
for i in range(len(tb)):
    print(tb[i].get('name'),tb[i].get('age'),tb[i].get('salary'),tb[i].get('city'))

字典核心底层原理

字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个 bucket有两部分︰一个是键对象的引用,一个是值对象的引

用。
由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket.

 将一个键值对放进字典的底层过程

a={}

a['name'] = 'shengtudai'

假设字典a对象创建完后,数组长度为8:

我们要把” name" =" gaoqi”这个键值对放到字典对象a中,首先第一步需要计算

 由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即"101”,十进制是数字5。我们查看偏移量5,对应的bucket是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即“100”,十进制是数学4。再查看偏移量为4的bucket是否为空。直到找到为空的bucket将键值对放进去。流程图如下:

 

 根据键查找“键值对”的底层过程

我们明白了,一个键值对是如何存储到数组中的,根据键对象取到值对象,理解起来就简单了。

当我们调用a.get("name”),就是根据键“name”查找到“键值对”,从而找到值对象“gaoqi” .

第一步,我们仍然要计算“name”对象的散列值∶

和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。假设数组长度为 8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字 5。我们查看偏移量5,对应的bucket是否为空。如果为空,则返回None。如果不为空, 则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对 应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完活%, 仍然没有找到。则返回None。流程图如下:

用法总结∶
1.键必须可散列
  (1)数字、字符串、元组,都是可散列的。
  (2)自定义对象需要支持下面三点∶
    ①支持hash()函数
    ②支持通过_eq_(方法检测相等性。
    ③若a==b为真,则hash(a)==hash(b)也为真。
2.字典在内存中开销巨大,典型的空间换时间。
3.键查询速度很快
4.往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。

原文地址:https://www.cnblogs.com/shengtudai/p/13591888.html