字典
内建数据类型,字典是python中最优秀的特性之一
字典即映射
字典与列表类似,但是更加通用。在列表中,索引必须是整数,它们几乎可以是任何类型
字典包含了一个索引的集合,被称为键,和一个值的组合。一个键对应一个值。这种一一对应的关联被称为键值对,有时也被称为项。
在数学语言中,字典表示的是从键到值的映射,所以也可以说每一个键映射到一个值。
dict函数生成一个不含任何项的新字典。是内建函数名
eng2sp = dict()
花括号{}表示一个孔子点,可以使用方括号向字典中添加项
eng2sp['one'] = 'uno'
这行代码创建一个新项,将键‘one’映射至值‘uno’,如果打印字典,会看到一个以冒号分隔的键值对
>>>eng2sp
>{'one':'uno'}
也可以通过类似的格式初始化字典
eng2sp = {'one':'uno',
'two':'dos',
'three':'tres'}
但是打印该字典会发现键值对的顺序可能改变,通常来说,字典中项的顺序是不可预知的
如果键不存在于字典中,会抛出一个异常
len函数也适用于字典,它返回键值对的个数
len(eng2sp)
in操作符也适用于字典,它可以用来检验字典中是否存在某个键(仅仅有值是无法检验的)
>>>'one' in eng2sp
>True
>>>'uno' in eng2sp
>False
想知道字典中是否存在某个值,可以使用values方法,它会返回值的集合,可以使用in来在这个集合中验证
vals = eng2sp.values()
>>>'uno' in vals
>True
in操作符对列表和字典采用不同的算法。对于列表,它按顺序依次查找目标,随着列表的增长,搜索时间成正比增长
对于字典,python使用一种叫做哈希表的算法,这种算法有一个特性:无论字典中有多少项,in运算符搜索所需的时间都是一样的。
字典作为计数器集合
假设有一个字符串,计算每个字母出现的次数,有以下方法
1.生成26个变量,每个对应一个字母表中的字母,然后可以遍历字符串,对于每个字符递增次数
2.生成具有26个元素的列表,将每个字符转化为一个数字,使用这些数字作为列表的索引,递增计数器
3.可以生成一个字典,将字符作为键,计数器作为相应的值。字母第一次出现,像字典中增加一项,之后,递增项中的值
实现是指执行某种计算的方法,有的实现更好。例如,使用字典的实现有一个有时,就是我们不需要事先知道字符串中有几种字母,只需要在出现新字母的时候分配空间
def histogram(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else:
d[c] += 1
return d
函数名是叫histogram(直方图),是计数器集合的统计术语
函数第一行生成一个孔子点。for循环遍历该字符串。每次循环,如果字典中不存在c这个子非鱼,可以生成一个新项初始值为1,如果c已经在字典中,那对相应的值加一
字典类有一个get方法,接受一个键和一个默认值作为参数。如果字典中存在该键,则返回对应值,否则返回传入的默认值
h = histogram('a')
>>>h.get('a',0)
>1
>>>h.get('b',0)
>0
循环和字典
在for循环中使用字典会遍历其所有的键
def print_hist(h):
for c in h:
print(c,h[c])
重点:字典中的键是无序的,如果要以确定的顺序遍历字典,可以使用内建方法sorted
for key in sorted(h):
print(key,h[key])
逆向查找
给定一个字典d以及一个键t,很容易找到相应的值。该运算被称作查找。
但是如果想通过值找到键呢。有两个问题
1.可能不止有一个键映射到这个值,可能需要使用list1将所有的键包起来
2.没有简单的语法可以完成逆向查找
def reverse_lookup(d,v):
for k in d:
if d[k] == v:
return k
raise LookupError()
raise语句能触发异常,这里触发了ValueError,这是一个表示查找操作失败的内建异常。
通过raise语句触发的异常和python触发产生的效果一样,都打印一条回溯和错误信息
raise语句接受一个也可以接受一个详细的错误信息作为可选的实参。