- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
5.1 字典数据类型
像列表一样,“字典”是许多值的集合。但不像列表的下标,字典的索引可以使用许多不同数据类型,不只是整数。字典的索引被称为“键”,键及其关联的值称为“键-值”对。
在代码中,字典输入时带花括号{}。在交互式环境中输入以下代码:
>>> myCat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'}
这将一个字典赋给myCat变量。这个字典的键是'size'、'color'和'disposition'。这些键相应的值是'fat'、'gray'和'loud'。可以通过它们的键访问这些值:
>>> myCat['size'] 'fat' >>> 'My cat has ' + myCat['color'] + ' fur.' 'My cat has gray fur.'
字典仍然可以用整数值作为键,就像列表使用整数值作为下标一样,但它们不必从0开始,可以是任何数字。
>>> spam = {12345: 'Luggage Combination', 42: 'The Answer'}
5.1.1 字典与列表
不像列表,字典中的表项是不排序的。名为spam的列表中,第一个表项是spam[0]。但字典中没有“第一个”表项。虽然确定两个列表是否相同时,表项的顺序很重要,但在字典中,键-值对输入的顺序并不重要。在交互式环境中输入以下代码:
>>> spam = ['cats', 'dogs', 'moose'] >>> bacon = ['dogs', 'moose', 'cats'] >>> spam == bacon False >>> eggs = {'name': 'Zophie', 'species': 'cat', 'age': '8'} >>> ham = {'species': 'cat', 'age': '8', 'name': 'Zophie'} >>> eggs == ham True
因为字典是不排序的,所以不能像列表那样切片。
尝试访问字典中不存在的键,将导致KeyError出错信息。这很像列表的“越界”IndexError出错信息。在交互式环境中输入以下代码,并注意显示的出错信息,因为没有'color'键:
>>> spam = {'name': 'Zophie', 'age': 7} >>> spam['color'] Traceback (most recent call last): File "", line 1, in spam['color'] KeyError: 'color'
尽管字典是不排序的,但可以用任意值作为键,这一点让你能够用强大的方式来组织数据。假定你希望程序保存朋友生日的数据,就可以使用一个字典,用名字作为键,用生日作为值。打开一个新的文件编辑窗口,输入以下代码,并保存为birthdays.py:
❶ birthdays = {'Alice': 'Apr 1', 'Bob': 'Dec 12', 'Carol': 'Mar 4'} while True: print('Enter a name: (blank to quit)') name = input() if name == '': break ❷ if name in birthdays: ❸ print(birthdays[name] + ' is the birthday of ' + name) else: print('I do not have birthday information for ' + name) print('What is their birthday?') bday = input() ❹ birthdays[name] = bday print('Birthday database updated.')
你创建了一个初始的字典,将它保存在birthdays中❶。用in关键字,可以看看输入的名字是否作为键存在于字典中❷,就像查看列表一样。如果该名字在字典中,你可以用方括号访问关联的值❸。如果不在,你可以用同样的方括号语法和赋值操作符添加它❹。
运行这个程序,结果看起来如下所示:
Enter a name: (blank to quit) Alice Apr 1 is the birthday of Alice Enter a name: (blank to quit) Eve I do not have birthday information for Eve What is their birthday? Dec 5 Birthday database updated. Enter a name: (blank to quit) Eve Dec 5 is the birthday of Eve Enter a name: (blank to quit)
当然,在程序终止时,你在这个程序中输入的所有数据都丢失了。在第 8章中,你将学习如何将数据保存在硬盘的文件中。
5.1.2 keys()、values()和items()方法
有3个字典方法,它们将返回类似列表的值,分别对应于字典的键、值和键-值对:keys()、values()和items()。这些方法返回的值不是真正的列表,它们不能被修改,没有append()方法。但这些数据类型(分别是dict_keys、dict_values和dict_items)可以用于for循环。为了看看这些方法的工作原理,请在交互式环境中输入以下代码:
>>> spam = {'color': 'red', 'age': 42} >>> for v in spam.values(): print(v) red 42
这里,for循环迭代了spam字典中的每个值。for循环也可以迭代每个键,或者键-值对:
>>> for k in spam.keys(): print(k) color age >>> for i in spam.items(): print(i) ('color', 'red') ('age', 42)
利用keys()、values()和items()方法,循环分别可以迭代键、值或键-值对。请注意,items()方法返回的dict_items值中,包含的是键和值的元组。
如果希望通过这些方法得到一个真正的列表,就把类似列表的返回值传递给 list函数。在交互式环境中输入以下代码:
>>> spam = {'color': 'red', 'age': 42} >>> spam.keys() dict_keys(['color', 'age']) >>> list(spam.keys()) ['color', 'age']
list(spam.keys())代码行接受keys()函数返回的dict_keys值,并传递给list()。然后返回一个列表,即['color', 'age']。
也可以利用多重赋值的技巧,在for循环中将键和值赋给不同的变量。在交互式环境中输入以下代码:
>>> spam = {'color': 'red', 'age': 42} >>> for k, v in spam.items(): print('Key: ' + k + ' Value: ' + str(v)) Key: age Value: 42 Key: color Value: red
5.1.3 检查字典中是否存在键或值
回忆一下,前一章提到,in和not in操作符可以检查值是否存在于列表中。也可以利用这些操作符,检查某个键或值是否存在于字典中。在交互式环境中输入以下代码:
>>> spam = {'name': 'Zophie', 'age': 7} >>> 'name' in spam.keys() True >>> 'Zophie' in spam.values() True >>> 'color' in spam.keys() False >>> 'color' not in spam.keys() True >>> 'color' in spam False
请注意,在前面的例子中,'color' in spam本质上是一个简写版本。相当于'color' in spam.keys()。这种情况总是对的:如果想要检查一个值是否为字典中的键,就可以用关键字in(或not in),作用于该字典本身。
5.1.4 get()方法
在访问一个键的值之前,检查该键是否存在于字典中,这很麻烦。好在,字典有一个get()方法,它有两个参数:要取得其值的键,以及如果该键不存在时,返回的备用值。
在交互式环境中输入以下代码:
>>> picnicItems = {'apples': 5, 'cups': 2} >>> 'I am bringing ' + str(picnicItems.get('cups', 0)) + ' cups.' 'I am bringing 2 cups.' >>> 'I am bringing ' + str(picnicItems.get('eggs', 0)) + ' eggs.' 'I am bringing 0 eggs.'
因为picnicItems字典中没有'egg'键,get()方法返回的默认值是0。不使用get(),代码就会产生一个错误消息,就像下面的例子:
>>> picnicItems = {'apples': 5, 'cups': 2} >>> 'I am bringing ' + str(picnicItems['eggs']) + ' eggs.' Traceback (most recent call last): File "<pyshell#34>", line 1, in 'I am bringing ' + str(picnicItems['eggs']) + ' eggs.' KeyError: 'eggs'
5.1.5 setdefault()方法
你常常需要为字典中某个键设置一个默认值,当该键没有任何值时使用它。代码看起来像这样:
spam = {'name': 'Pooka', 'age': 5} if 'color' not in spam: spam['color'] = 'black'
setdefault()方法提供了一种方式,在一行中完成这件事。传递给该方法的第一个参数,是要检查的键。第二个参数,是如果该键不存在时要设置的值。如果该键确实存在,方法就会返回键的值。在交互式环境中输入以下代码:
>>> spam = {'name': 'Pooka', 'age': 5} >>> spam.setdefault('color', 'black') 'black' >>> spam {'color': 'black', 'age': 5, 'name': 'Pooka'} >>> spam.setdefault('color', 'white') 'black' >>> spam {'color': 'black', 'age': 5, 'name': 'Pooka'}
第一次调用setdefault()时,spam变量中的字典变为{'color': 'black', 'age': 5, 'name': 'Pooka'}。该方法返回值'black',因为现在该值被赋给键'color'。当spam.setdefault('color', 'white')接下来被调用时,该键的值“没有”被改变成'white',因为spam变量已经有名为'color'的键。
setdefault()方法是一个很好的快捷方式,可以确保一个键存在。下面有一个小程序,计算一个字符串中每个字符出现的次数。打开一个文件编辑器窗口,输入以下代码,保存为characterCount.py:
message = 'It was a bright cold day in April, and the clocks were striking thirteen.' count = {} for character in message: count.setdefault(character, 0) count[character] = count[character] + 1 print(count)
程序循环迭代message字符串中的每个字符,计算每个字符出现的次数。setdefault()方法调用确保了键存在于count字典中(默认值是0),这样在执行count[character] = count[character] + 1时,就不会抛出KeyError错误。程序运行时,输出如下:
{' ': 13, ',': 1, '.': 1, 'A': 1, 'I': 1, 'a': 4, 'c': 3, 'b': 1, 'e': 5, 'd': 3, 'g': 2, 'i': 6, 'h': 3, 'k': 2, 'l': 3, 'o': 2, 'n': 4, 'p': 1, 's': 3, 'r': 5, 't': 6, 'w': 2, 'y': 1}
从输出可以看到,小写字母c出现了3次,空格字符出现了13次,大写字母A出现了1次。无论message变量中包含什么样的字符串,这个程序都能工作,即使该字符串有上百万的字符!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论