Python Cookbook-4.11 在无须过多援引的情况下创建字典
任务
在无须过多援引的情况下创建字典。
解决方案
当你逐渐习惯了 Python,会发现自己已经创建了大量的字典。当键是标识符时,可以用 dict 加上命名的参数来避免援引它们:
data = dict(red = 1, green = 2, blue = 3)
这看上去比直接用字典形式的语法要整洁一些
data = {'red':1, 'green':2, 'blue':3}
讨论
一种创建字典的好方法是调用内建的 dict 类型,但有时用带有花括号和冒号的字典形式也不错。本节的代码说明,如果键都是文字的字符串并且在语法上对用户而言也是有效且适合作为标识符的,则通过调用 dict,无须援引字典的键。不能对像“12ba”和“for”一样的字符串应用此法,因为“12ba”以数字开头,而 for 正好是 Python 关键字不能作为标识符。
字典形式的语法是 Python 中唯一需要用到花括号的地方:如果不喜欢花括号,或者正好所用的键盘不太容易打出花括号(所有的意大利布局的键盘都这样),那么可以用dict()而不是{}来创建一个空字典。
调用 dict 还能给你带来一些其他额外的好处。dict(d)返回一个完全独立于原字典d的拷贝,就像 d.copy()一样。但当d不是一个字典,而是一个数对(key,value)的序列时,dict(d)仍然有效(如果 key在序列中出现多次,那么只有最后一次出现的 key 会被计入)。般创建字典的操作大概是这样:
d = dict(zip(the_keys,the_values))
the_key 是键的序列,the_values 则是键的对应值的序列。内建的 zip 函数创建并返回一个数对(key,value)构成的列表,内建类型 dict 接受这个列表作为参数并创建相应的字典。如果序列非常长,那么用Python 标准库中的itertoos模块能有效地提高速度:
import itertools
d = dict(itertools.izip(the_keys,the_values))
内建函数 zip 会在内存中创建出包含所有数对的列表,而 itertools.izip 一次只生成一对数据。在一些计算机上,对于长度为10000的序列,后面这种方式可以快两倍左右——Python2.3中是18ms对45ms,Python2.4中则是17ms对32ms。
还可以在 dict 调用中使用基于位置的参数和命名参数(如果命名的参数正好和基于位置的参数冲突,则前者生效)。举个例子,下面是一个字典的创建,其中用到了前面提到的 Python 关键字和另一个不宜做命名参数的键名:
d = dict({'12ba':49, 'for':23),rof = 41, fro = 97, orf = 42)
如果想创建一个字典,其中每个键都对应相同的值,只需调用dict.fromkeys(keysequence,value)(如果你忽略了value,它默认使用None)即可。下面给个例子,用很清爽的方式初始化一个字典,并用它来统计不同的小写ASCI字母的出现次数:
import string
count_by_letter = dict.fromkeys(string.ascii_lowercase, 0)