与列表相比的特点:
列表中的索引位置必须是整数,而字典中索引几乎可以是任意类型。
字典
字典可看作是索引(这里称为键)的集合与值的集合之间存在的一种映射。
每个键对应一个值,键与值之间的关系称之为键值对,有时也称为数据项。
dict函数(内置函数)可以创建一个空字典。
>>> eng2sp = dict()
>>> print eng2sp
{}
大括号{}表示一个空字典。你可以使用方括号向字典里添加数据项。
>>> eng2sp['one'] = 'uno'
这行语句创建了一个从键“one”到值“uno”映射的字典项。如果再次打印这个字典,我们会看到一个键值对,键与值之间用冒
号隔开。
>>> print eng2sp
{'one': 'uno'}
字典的输入形式与输出形式是一样的。举例来说,你可以创建一个包含三个数据项的字典:
>>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
但是,如果你直接打印eng2sp,其结果会出人意料:
>>> print eng2sp
{'one': 'uno', 'three': 'tres', 'two': 'dos'}
输出的键值对顺序发生了改变。一般而言,字典的顺序往往不可预测。
这个无所谓。因为字典项不是用整数来索引,而是采用键来查找对应的值。
>>> print eng2sp['two']
'dos'
键“two”对应的值是“dos”,这与字典项的顺序无关。
len函数也适用于字典,它会返回字典中键值对的个数。
>>> len(eng2sp)
3
in操作符也适用于字典,它会告知你查找的东西是否作为键存在于字典中,但不能对是否是值作出很好的判断。
>>> 'one' in eng2sp
True
>>> 'uno' in eng2sp
False
为了判断要找的东西是否作为值存在于字典中,使用values方法,它会返回字典中所有值的一个列表,然后使用in操作符作
出判断。
>>> vals = eng2sp.values()
>>> 'uno' in vals
True
字典作为计数器
字典实现的一个优点在于,我们不必事先知道字符串中出现了哪些字母,只需为确实会出现的字母分配空间就好了。
word = 'brontosaurus'
d = dict()
for c in word:
if c not in d:
d[c] = 1
else:
d[c] = d[c] + 1
print d
每次循环时,如果字符c不在字典中,我们就创建一个字典项,以c为键,初始值1(表示这个字母至此出现了一次)。如果c已经存在于字典中,只需将对应值d[c]加1即可。
字典有一个get方法,该方法拥有一个键和一个默认值。**如果键出现在字典中,那么它会返回此键对应的值。如果键不在字典
中,返回事先给定的默认值**。示例程序如下:
>>> counts = {'chuck':1 ,'annie':42,'jan':100}
>>> print counts.get('jan', 0)
100
>>> print counts.get('tim', 0)
0
我们使用get方法可以把直方图循环写得更简洁。因为get方法自动处理了键不在字典中的情况。这样的话,代码的4条语句可
缩减至1条,还可以去掉if语句。
word = 'brontosaurus'
d = dict()
for c in word:
d[c] = d.get(c,0) + 1
print d
使用get方法简化计数循环的做法已经成为Python中的一种普遍做法。
字典与文件
字典的常见用法之一是对书面文字的文本文件进行词频统计。
编写一个Python程序,读取文件的每一行,并将每一行*分解为由单词组成的一个列表*。然后,遍历每个单词,使用字典来统计每个单词的出现次数。
fname = raw_input('Enter the file name: ')
try:
fhand = open(fname)
except:
print 'File cannot be opened:', fname
exit()
counts = dict()
for line in fhand:
words = line.split() #通过指定字符对字符串进行切片
for word in words:
if word not in counts:##这句话注意怎么写***
counts[word] = 1
else:
counts[word] += 1
print counts
split()方法 :通过指定字符对字符串进行切片
循环与字典
通过for语句循环读取每一个键及其对应的值:
counts = { 'chuck':1, 'annie':42,'jan':100}
for key in counts:
print key,counts[key]
程序运行结果如下:
jan 100
chuck 1
annie 42
如果按照字母顺序输出字典中的键,首先使用字典对象的keys方法,将所有的键放入一个列表。然后,对这个列表进行排
序,对排序后的列表进行迭代。依照字母顺序,通过每个键输出对应的键值对:
counts = {'chuck':1,'annie':42,'jan':100}
lst = counts.keys()
print lst
lst.sort()
for key in lst:
print key,counts[key]
程序运行的输出结果如下:
['jan', 'chuck', 'annie']
annie 42
chuck 1
jan 100
首先,通过keys方法得到了包含键的未排序的列表。然后,通过for循环得到有序的键值对。
高级文本解析
实际的文本会包含大量标点符号:
通过字符串的lower(大小写转换)、punctuation(列出标点符号需要哪些字符)与translate(删除指定的所有字符)方法可以解决上述问题。其中translate是最精细的方法。
Translate方法使用:
string.translate(s, table[, deletechars])
首先,从s中删除deletechars参数(如果存在的话)指定的所有字符,然后使用table参数来翻译字符。table是一个256个字
符长的字符串,用来翻译每个字符值,并按照序数进行索引。如果table是None值,只会执行字符删除步骤。
这里不指定table参数,用deletechars参数来删除所有标点符号。
Python甚至可以告诉我们,标点符号包括哪些字符:
>>> import string
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
我们对程序做出如下修改:
import string
#New Code
fname = raw_input('Enter the file name:')
try:
fhand = open(fname)
except:
print 'File cannot be opened:',fname
exit()
counts = dict()
for line in fhand:
line = line.translate(None, string.punctuation)
#New Code 这行代码好好看看
line = line.lower()
#New Code
words = line.split()
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
print counts
我们使用translate方法删除了所有的标点符号,并将每一行中的字母转换为小写。
查看这些输出仍然很费事,让Python来帮助我们找到具体要找到的信息。要做到这一点,我们需要学习Python的元组。
调试
编写自检程序:
有时通过编写代码来自动检查错误。例如,需要计算数字列表的平均数,你可以检查这个结果是不是处于列
表的最大值与最小值之间。这种检查称为“逻辑检查”,它会检测出哪些结果是完全不符合逻辑的。
一致性检查
比较两种不同计算的结果,检查它们是否一致。。
工整化输出结果:
对调试的输出结果进行格式化,这有助于发现错误。
再次强调,在程序架构上花些心思能有效减少调试的时间花费。