字典实战——字典用法说明——字典中的嵌套

未匹配的标注

可以看到:字典在Python中可以扮演很多角色。通常它们可以替换搜索数据结构(因为按键索引是一个搜索操作)和可以表示许多类型的结构化信息。比如,字典是描述程序域中一个项的属性的许多方式之一;也即是说,它们可以起到其它语言中的”记录“或”结构“的相同作用。

比如,下面通过逐渐分配新的键来填充一个描述假想的人的字典:

>>> rec = {}
>>> rec['name'] = 'Bob'
>>> rec['age'] = 40.5
>>> rec['job'] = 'developer/manager'
>>>
>>> print(rec['name'])
Bob

特别当嵌套时,Python的内置数据类型允许轻松地表示结构化的信息。下面再次使用字典来捕获对象属性,但它是一次性编码(而非单独对每个键赋值)且嵌套了列表和字典来表示结构化的属性值:

>>> rec = {'name': 'Bob',
... 'jobs': ['developer', 'manager'],
... 'web': 'www.bobs.org/ ̃Bob',
... 'home': {'state': 'Overworked', 'zip': 12345}}

要获取嵌套对象的组件,只需要将索引操作串起来:

>>> rec['name']
'Bob'
>>> rec['jobs']
['developer', 'manager']
>>> rec['jobs'][1]
'manager'
>>> rec['home']['zip']
12345

虽然在第6部分将学到:(它同时对数据和逻辑分组)可以更好的记录,但字典是对更简单需求的易用工具。要获取更多关于记录表示的选择的知识,还请参见接下来的侧边栏为什么你要关心:字典 vs 列表,还有在第9章中的元组扩展和第27章中的类。

还注意:虽然一直关注使用嵌套数据的单个”记录“,但没有理由不将记录本身嵌套在更大的,封闭的编码为列表或字典的数据库集合中,然而外部文件或正式的数据库接口通常扮演现实程序中的顶层容器的角色:

db = []
db.append(rec) # A list "database"
db.append(other)
db[0]['jobs']
db = {}
db['bob'] = rec # A dictionary "database"
db['sue'] = other
db['bob']['jobs']

本书稍后将碰到如Python的shelve等工具,它们工作原理大致相同,但自动将对象和文件相互映射从而使其永久存在(在本章的侧边栏为什么你要关心:字典接口中关注更多)


为什么你要关心:字典 vs 列表

考虑到Python的核心类型武器库中的所有对象,一些读者可能对于列表和字典的选择感到困惑。简言之,虽然两个都是其它对象的灵活集合,但列表将项分配给位置,而字典分配给更容易记忆的。因此,字典数据通常对人类读者更有意义。比如,在表8-1中的行3的嵌套列表结构也可以用来表示一个记录:

>>> L = ['Bob', 40.5, ['dev', 'mgr']] # List-based "record"
>>> L[0]
'Bob'
>>> L[1] # Positions/numbers for fields
40.5
>>> L[2][1]
'mgr'

对于一些数据类型,列表的按位置访问有意义——比如,公司中的雇员列表,文件夹中的文件,或数字矩阵。但像这个的更符号化的记录可能编码为表8-2中行2的字典更有意义,使用标记过的字典替代字段位置(这类似于第4章中编码的一个记录):

>>> D = {'name': 'Bob', 'age': 40.5, 'jobs': ['dev', 'mgr']}
>>> D['name']
'Bob'
>>> D['age'] # Dictionary-based "record"
40.5
>>> D['jobs'][1] # Names mean more than numbers
'mgr'

为了多样性,这是使用关键字的被记录的同样的记录,它看起来对一些人类读者可能更可读:

>>> D = dict(name='Bob', age=40.5, jobs=['dev', 'mgr'])
>>> D['name']
'Bob'
>>> D['jobs'].remove('mgr')
>>> D
{'jobs': ['dev'], 'age': 40.5, 'name': 'Bob'}

在实践中,字典往往对有标签化组件的数据是最好的,还有能受益于通过名称快速、直接查找而非更慢的线性搜索的结构。已经看到:它们还可能更好的用于稀疏集合和在任意位置增长的集合。

Python程序员还能访问在第5章中学习的sets,它很像一个无值字典的键;它们不映射键到值,但当没有关联值时,通常能被像字典那样用来快速查找,特别是在搜索程序中:

>>> D = {}
>>> D['state1'] = True # A visited-state dictionary
>>> 'state1' in D
True
>>> S = set()
>>> S.add('state1') # Same, but with sets
>>> 'state1' in S
True

关注在下一章中这个记录表现主题的重新讨论,在那里将了解元组命名元组是如何在这个作用中与字典比较的,还有在第27章,在那里将学习如何将用户自定义的包括进整体理解(结合数字和处理它的逻辑)。


为什么你要关心:字典接口

 字典不只是在程序中通过键存储信息的一种方便的方式——一些Python扩展也提供了看起来和工作起来都很像字典的接口。比如,Python的DBM 按键访问文件的接口看起来非常像必须被打开的字典。使用键的索引来存储和获取字符串:

import dbm # Named anydbm in Python 2.X
file = dbm.open("filename") # Link to file
file['key'] = 'data' # Store data by key
data = file['key'] # Fetch data by key

第28章,如果使用shelve(shelves 是按键访问的存储持续的Python对象而不只是字符串的数据库)替换之前代码中的dbm,将看到还可以用这种方式存储整个Python对象。对Internet的工作,Python的CGI脚本支持还提供了一个类字典的接口。对cgi.FieldStorage的一次调用产生了一个类字典的对象,客户端网页上的每个输入字段就是它的一个条目:

import cgi
form = cgi.FieldStorage() # Parse form data
if 'name' in form:
showReply('Hello, ' + form['name'].value)

然而字典是唯一的核心映射类型,这些其它的都是映射实例,且支持大部分相同操作。一旦学会了字典接口,会发现它们应用于Python中许多内置工具。

对另一个字典用例,请参见第9章的对JSON接下来的总览——一个语言中立的数据格式,用于数据库和数据传输。Python的字典、列表和它们的嵌套组合几乎都能以这种格式按原样被作为记录,而且可以使用Python的 json 标准库模块轻松地与JSON 文本字符串相互转换。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~