• 谈谈Python中最灵活的内置数据结构类型-字典
  • 发布于 2个月前
  • 297 热度
    0 评论
  • Love5G
  • 1 粉丝 9 篇博客
  •   
字典是 Python 中最灵活的内置数据结构类型之一,它可以取代许多数据结构和搜索算法,而这些在别的语言中你可能需要手动来实现。

一旦熟练的掌握了字典,它将会成为一种非常简单的工具。比如对字典进行索引是一种非常快速的搜索方式,当然它的作用不止于此,接下来我们就一起来盘一盘字典那些“灵活”的操作。

01.字典用于模拟列表

我们都知道在使用列表的时候,在其末尾外的下标进行赋值是非法的:
>>> lst = []
>>> lst[9] = 9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
虽然我们可以用诸如 [0] * 10 的方式做初始化,预先分配足够大的列表,但这样显得有点太笨了,这个时候我们可以选择字典来做类似的事情。

使用整数键的时候,字典可以模拟列表在给下标赋值时增长,这样就不需要像之前那样预先进行空间分配:
>>> dit = {}
>>> dit[9] = 9
>>> dit[9]
9
>>> dit
{9: 9}

在上面的代码中,字典看起来就像是一个有 10 个元素的列表,实际上它里面只有一个元素,key 9 的 value 是整数 9,在这里我们可以像列表那样用下标访问这个结构,但是又不需要对可能会被赋值的所有位置都分配空间。

02.字典用于稀疏数据结构

在文章刚开始的时候我说过,字典可以取代许多数据结构,常用的在实现稀疏数据结构上。比如有一个三维数组,这个数组只有少数的几个位置有值,其它的位置都为空,这个时候我们用字典来实现一下:
>>> matrix = {}
>>> matrix[(1,2,3)] = 123
>>> matrix[(4,5,6)] = 456
>>> x = 1
>>> y = 2
>>> z = 3
>>> matrix[(x,y,z)]
123
>>> matrix
{(1, 2, 3): 123, (4, 5, 6): 456}

在上面的代码中,我们用字典表示了一个三维数组,key 是元组形式,它们记录了非空位置上的坐标,而不是去做一个庞大的且几乎为空的三维矩阵。

同理,对于多维数组也是一个做法。这里要注意的是,因为是字典的形式,所以读取空元素的时候 Python 会报错,因为这些元素实际上并没有存储:
>>> matrix[(7,8,9)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: (7, 8, 9)
上面的这种错误在稀疏矩阵中是很常见的,但是我们并不希望程序因为这个错误而停止,那么该如何做呢?

据我所知至少有三种方式可以让我们不会出现这样的错误提示:

在 if 中预先对 key 进行测试;
使用 try 捕获这个异常,并且修复它;
使用 get 方法为不存在的 key 提供一个默认值。
具体的操作如下所示:
>>> if (7,8,9) in matrix:
... print(matrix[(7,8,9)])
... else:
... print('key error')
... 
key error
>>> try:
... print(matrix[(7,8,9)])
... except KeyError:
... print('key error')
... 
key error
>>> matrix.get((1,2,3),'key error')
123
>>> matrix.get((7,8,9),'key error')
'key error'
仅是通过上面的代码来看的话,get 方法是用起来最舒服的。

03.字典用于结构化类型

还是在开头说过的字典可以取代许多数据结构和搜索算法,并且可以表示多种结构化信息的类型,比如通过向新 key 赋值来增加字典元素:
>>> info = {}
>>> info['name'] = 'rocky'
>>> info['age'] = 23
>>> info['sex'] = 'man'
>>> info
{'name': 'rocky', 'age': 23, 'sex': 'man'}

上面的代码表现力可能还差一点,当为「嵌套」的时候,字典表达结构化信息的轻松才算是很好的呈现在我们眼前:
>>> info = {'name':'rocky',
... 'info':{'age':'23','sex':'man'},
... 'job':['writer','coder']}

上面的字典一气呵成,嵌套了一个字典和一个列表来表示结构化属性的值,当我们想要读取嵌套对象的元素时,只要简单的把索引串起来就可以了:
>>> info['name']
'rocky'
>>> info['job']
['writer', 'coder']
>>> info['job'][1]
'coder'
>>> info['info']
{'age': '23', 'sex': 'man'}
>>> info['info']['sex']
'man'

04.字典的注意事项

我们在欢快的使用字典带来的便利的时候,也要有几点需要我们注意。

首先是对字典的序列运算是做“无用功”。这一点相信很多人都清楚,字典是一种映射机制,不是序列。字典元素中之间没有顺序的概念,类似有序合并或者是切片这种运算对字典是不能用的。实际上,如果你尝试这么做,Python 会在你的程序运行时给你个报错 see see。

再者字典中的 key 不一定总是字符串,任何「不可变」的对象都是可以的(这就意味着列表等可变的对象是不可以的),比如我们在上面的例子中用整数和元组当过字典的 key 值。
用户评论