- 字典定义:Python中的字典不是一个序列,而是一种映射(mapping)。映射是一个其他对象的集合,但是它们是通过键而不是相对位置来存储 的。实际上,映射并没有任何可靠的从左至右的顺序。它们简单地将键映射到值。字典是Python核心对象集合中唯一的一种映射类型,也具有可变性。
- 映射操作。作为常量编写时,字典编写在大括号中,并包含一些列的{键:值}对。
In [1]: D = {'food':'Spam','quantity':4,'color':'pink'} In [2]: D['food'] Out[2]: 'Spam' In [3]: D['quantity'] += 1 In [4]: D Out[4]: {'color': 'pink', 'food': 'Spam', 'quantity': 5}
不同的创建字典的方法。下面开始一个空字典,然后每次以一个键俩填写它。与列表中禁止边界外的赋值不同,对于一个新的字典的键赋值会创建该键
In [1]: D = {} In [2]: D['name'] = 'Bob' In [3]: D['job'] = 'dev' In [4]: D['age'] = 40 In [5]: D Out[5]: {'age': 40, 'job': 'dev', 'name': 'Bob'} In [6]: print(D['name']) Bob
字典也可以用来执行搜索。通过键索引一个字典往往是Python中编写搜索的最快的方法。
- 重访嵌套。假设信息更复杂,一次将所有的内容编写进一个常量,将可以记录更多结构化信息。
In [1]: rec = {'name':{'first':'Bob','last':'Smith'},'job':['dev','mgr'],'age':40.5} In [2]: rec['name'] Out[2]: {'first': 'Bob', 'last': 'Smith'} In [3]: rec['name']['last'] Out[3]: 'Smith' In [4]: rec['job'] Out[4]: ['dev', 'mgr'] In [5]: rec['job'][-1] Out[5]: 'mgr' In [6]: rec['job'].append('janitor') In [7]: rec Out[7]: {'age': 40.5, 'job': ['dev', 'mgr', 'janitor'], 'name': {'first': 'Bob', 'last': 'Smith'}}
注意这里的最后一个操作是如何扩展嵌入job列表的。因为job列表是字典所包含的一部分独立的内存,它可以自由地增加或减少。
- 键的排序:for循环作为映射,字典仅支持通过键获取元素,尽管这样,在各种常见的应用场合,通过调用方法,它们也支持类型特定的操作。因为字典不是序列,不包含任何可 靠的顺序,但是我们如果确实要强调某种顺序的时候,可以通过字典的keys方法收集一个键的列表,使用列表的sort方法进行排序,然后使用Python 的for循环逐个进行显示结果。
In [1]: D = {'a':1,'b':2,'c':3} In [2]: D Out[2]: {'a': 1, 'b': 2, 'c': 3} In [3]: Ks = list(D.keys()) In [4]: Ks Out[4]: ['b', 'a', 'c'] In [5]: Ks.sort() In [6]: Ks Out[6]: ['a', 'b', 'c'] In [7]: for key in Ks: ...: print(key,'=>',D[key]) ...: a => 1 b => 2 c => 3
在Python3中,通过最新的sorted内置函数可以一步完成。sorted调用返回结果并对各种对象类型进行排序。
In [8]: for key in sorted(D): ....: print(key,'=>',D[key]) ....: a => 1 b => 2 c => 3
这种情况就是学习Python的for循环的理由。for循环是遍历一个序列中的所有元素并按照顺序对每个元素运行一些代码的简单并有效的措施。一 个用户定义的循环变量(这里是key)用做每次运行过程中当前元素的参考量。for循环以及其作用与while循环相似,是在脚本编写重复性语句的主要方 法。事实上,for循环就像列表解析一样是一个序列操作。它可以使用在任意一个序列对象,并且就像列表解析一样,甚至可以用在一些不是序列的对象中。例 如,for循环可以步进循环字符串中的字符串,打印每个字符串的大写
In [1]: for c in 'spam': ...: print(c.upper()) ...: S P A M
Python的while循环是一种更为常见的排序循环工具,它不仅限于遍历序列:
In [1]: x = 4 In [2]: while x > 0: ...: print('spam!' * x) ...: x -= 1 ...: spam!spam!spam!spam! spam!spam!spam! spam!spam! spam!
- 迭代和优化如果for循环看起来就像是列表解析式一样,也没错,它们都是真正的通用迭代工具。事实上,它们都能够工作于遵从迭代协议(这是Python种无处 无在的一个概念,表示在内存中物理存储的序列,或一个在迭代操作情况下每次产生的一个元素的对象)的任意对象如果一个对象在响应next之前先用一个对象 iter内置函数做出了响应,那么它属于后一种情况。我们在上一笔记中见到的生成器解析表达式就是一样的一个对象。
从左到右扫描一个对象的每个Python工具都使用迭代协议。这就是为什么sorted调用直接工作于字典之上,我们不必调用keys方法来得到一个序列,因为字典是可迭代的对象,可以用一个next返回后续的键。这也意味着任何列表解析表达式都可以计算一列数字的平方:
In [1]: squares = [x ** 2 for x in [1,2,3,4,5]] In [2]: squares Out[2]: [1, 4, 9, 16, 25] In [3]: squares = [] In [4]: for x in [1,2,3,4,5]: ...: squares.append(x ** 2) ...: In [5]: squares Out[5]: [1, 4, 9, 16, 25]
尽管如此,列表解析和相关的函数编程工具,如map和filter,通常运行得比for循环快,这是对有大数据结合的程序有重大影响的特性之一,在Python中性能测试是一个很难应付的任务,因为它在反复的优化,版本之前差别很大。
Python中的一个主要原则就是,首先为了简单和可读性去编写代码,在程序可以工作,并证明了确实有必要考虑性能后,再考虑该问题。利用time以及timeit模块和profile模块。
- 不存在的键:if测试 尽管我们能够通过给新的键赋值来扩展字典,但是获取一个不存在的键值仍然是一个错误
In [1]: D = {'a':1,'c':3,'b':2} In [2]: D['e'] = 99 In [3]: D Out[3]: {'a': 1, 'b': 2, 'c': 3, 'e': 99} In [4]: D['f'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) in () ----> 1 D['f'] KeyError: 'f'
要避免错误发生,首先进行测试,in关系表达式允许我们查询字典中的一个键是否存在,并可以通过if语句对结果进行分支处理:
In [5]: 'f' in D Out[5]: False In [6]: if not 'f' in D: ...: print('missing') ...: missing
默认情况下,if语句也有else分句,以及一个或多个elif(else if)分句进行其它测试。它是Python主要的选择工具,并且是在脚本中编写逻辑的方法。
这里还有其它方法来创建字典并避免获取不存在的键:get方法(带有一个默认值的条件索引),try语句(一个捕获异常并从异常中恢复的工具),以及if/else表达式(实际上是挤在一行中的一条if语句)
In [7]: value = D.get('x',0) In [8]: value Out[8]: 0 In [9]: value = D['x'] if 'x' in D else 0 In [10]: value Out[10]: 0 In [11]: D Out[11]: {'a': 1, 'b': 2, 'c': 3, 'e': 99}
分类: Python3
0 条评论