- 译者序
- 前言
- 第1章 问答环节
- 第2章 Python 如何运行程序
- 第3章 如何运行程序
- 第4章 介绍 Python 对象类型
- 第5章 数字
- 第6章 动态类型简介
- 第7章 字符串
- 第8章 列表与字典
- 第9章 元组、文件及其他
- 第10章 Python 语句简介
- 第11章 赋值、表达式和打印
- 第12章 if 测试和语法规则
- 第13章 while 和 for 循环
- 第14章 迭代器和解析,第一部分
- 第15章 文档
- 第16章 函数基础
- 第17章 作用域
- 第18章 参数
- 第19章 函数的高级话题
- 第20章 迭代和解析,第二部分
- 第21章 模块:宏伟蓝图
- 第22章 模块代码编写基础
- 第23章 模块包
- 第24章 高级模块话题
- 第25章 OOP:宏伟蓝图
- 第27章 更多实例
- 第28章 类代码编写细节
- 第29章 运算符重载
- 第30章 类的设计
- 第31章 类的高级主题
- 第32章 异常基础
- 第34章 异常对象
- 第35章 异常的设计
- 第36章 Unicode 和字节字符串
- 字符串基础知识
- Python 的字符串类型
- 文本和二进制文件
- Python 3.0 中的字符串应用
- 转换
- 编码 Unicode 字符串
- 编码非ASCII文本
- 编码和解码非ASCII文本
- 其他 Unicode 编码技术
- 转换编码
- 在 Python 2.6 中编码 Unicode 字符串
- 源文件字符集编码声明
- 使用 Python 3.0 Bytes 对象
- 序列操作
- 创建 bytes 对象的其他方式
- 混合字符串类型
- 使用 Python 3.0(和 Python 2.6)bytearray 对象
- 使用文本文件和二进制文件
- Python 3.0 中的文本和二进制模式
- 类型和内容错误匹配
- 使用 Unicode 文件
- 在 Python 3.0 中处理 BOM
- Python 2.6 中的 Unicode 文件
- Python 3.0 中其他字符串工具的变化
- Struct二进制数据模块
- pickle对象序列化模块
- XML解析工具
- 本章小结
- 本章习题
- 习题解答
- 第37章 管理属性
- 第38章 装饰器
- 第39章 元类
- 附录A 安装和配置
- 附录B 各部分练习题的解答
- 作者介绍
- 封面介绍
集合
因为它是其他对象的集合,因此,它具有列表和字典这样的对象的某些共同行为,而这些对象超出了本章讨论的范围。例如,集合是可以迭代的,可以根据需要增长或缩短,并且能够包含各种对象类型。我们将会看到,一个集合的行为很像一个无值的字典的键,但是,它还支持额外的操作。
然而,由于集合是无序的,并且不会把键匹配到值,它们既不是序列也不是映射类型;它们是自成一体的类型。此外,由于集合本质上具有基本的数学特性(它对于很多读者来说,可能更加学院派,并且比像字典这样更为普遍的对象用得要少很多),在这里,我们将介绍Python的集合对象的基本工具。
Python 2.6中的集合基础知识
根据你使用的是Python 2.6还是Python 3.0,有几种不同方法来创建集合。既然本书涉及这两个版本,让我们先从Python 2.6的情况开始,其方法在Python 3.0中也是可用的(并且有时候还是必须的);稍后,我们将根据Python 3.0的扩展来细化。要创建一个集合对象,向内置的set函数传递一个序列或其他的可迭代的对象:
得到了一个集合对象,其中包含传递的对象的所有元素(注意集合并不包含位置顺序,序列却包含):
集合通过表达式操作符支持一般的数学集合运算。注意,不能在一般序列上应用这些表达式,必须通过序列创建集合后才能使用这些工具。
除了表达式,集合对象还提供了对应这些操作的方法,以及更多的支持改变集合的方法,集合add方法插入一个项目、update是按位置求并集,remove根据值删除一个项目(在任何集合实例或集合类型名上运行dir来查看所有可用的方法)。假设x和y仍然像前面交互中的一样:
作为可迭代的容器,集合也可以用于len、for循环和列表解析这样的操作中。然而,由于它们都是无序的,所以不支持像索引和分片这样的操作:
最后,尽管前面介绍的集合表达式通常需要两个集合,它们基于方法的对应形式往往对任何可迭代类型也有效:
要了解关于集合操作的更多细节,参阅Python的库参考手册,或者其他参考书。尽管集合操作可以在Python中和其他类型(如列表和字典)一起手动编写,Python的内置集合还是使用高效率的算法和实现技术来提供快速和标准的操作。
Python 3.0中的集合常量
如果你认为集合很“酷”,它们最近会变得更酷。在Python 3.0中,我们仍然使用集合内置函数来创建集合对象,但是Python 3.0也添加了新的集合常量形式,该形式使用前面为字典所保留的花括号。在Python 3.0中,如下的形式是等同的:
这个语法是有意义的,因为集合基本上就像是无值的字典,集合的项是无序的、唯一的、不可改变的,因此,它们的行为和字典的键很像。由于字典键列表在Python 3.0中是视图对象,它支持像交集和并集这样的类似集合的行为,这种相似性甚至更加惊人(参见第8章了解关于字典视图对象的更多内容)。
实际上,不管如何创建集合,Python 3.0都使用新的常量格式来显示它。在Python 3.0中要创建空的集合或从已有的可迭代对象构建集合(使用集合解析的简述,将在本章稍后介绍),还是需要内置的set函数,但是新的常量便于初始化具有已知结构的集合:
前面小节中所讨论的所有集合处理操作在Python 3.0中都同样有效,但是结果集合显示有所不同:
注意,在Python中{}仍然是一个字典。空的集合必须通过内置函数set来创建,并且以同样方式显示:
与Python 2.6一样,Python 3.0中用常量创建的集合支持同样的方法,其中的一些支持表达式所不支持的通用可迭代操作数:
不可变限制和冻结集合
集合是强大而灵活的对象,但是,它们在Python 3.0和Python 2.6中都有一个限制,我们需要铭记,很大程度上是由于其实现,集合只能包含不可变的(即可散列的)对象类型。因此,列表和字典不能嵌入到集合中,但是,如果你需要存储复合值的话,元组是可以嵌入的。在集合操作中使用元组的时候,元组比较其完整的值:
例如,集合中的元组可以用来表示日期、记录、IP地址等(本书的本部分后续将更详细地介绍元组)。集合本身也是不可改变的,因此,不能直接嵌入到其他集合中;如果需要在另一个集合中存储一个集合,可以像调用set一样来调用frozenset,但是,它创建一个不可变的集合,该集合不可修改并且可以嵌套到其他集合中。
Python 3.0中的集合解析
除了常量,Python 3.0还引入了一个集合解析构造,它类似于我们在第4章中介绍过的列表解析的形式,但是,编写在花括号中而不是方括号中,并且作用于集合而不是列表。集合解析运行一个循环并在每次迭代时收集一个表达式的结果,通过一个循环变量来访问当前的迭代值以用于集合表达式中。结果是通过运行代码创建的一个新的集合,它具备所有一般的集合行为:
在这个表达式中,循环部分编写在右边,而集合表达式编写在左边(x**2)。和列表解析一样,我们可以很好地理解这个表达式的含义:“对于列表中的每一个X,给出包含X的平方的一个新的集合”。解析也可以迭代其他类型的对象,例如字符串(下面的第一个例子展示了如何从一个已有的可迭代对象创建一个集合):
因为其他的关于解析的知识要依赖于我们现在还不准备介绍的底层概念,这些概念将推迟到本书后面再详细介绍。在第8章中,我们将遇到Python 3.0中的另一种解析,即字典解析,并且,我们随后将介绍关于所有解析(列表、集合、字典和生成器)的更多内容,特别是在第14章和第20章中。随后你将会了解到,在没有学习较大的语句之前,很难理解所有的解析,包括集合、这里所没有介绍的其他语法的支持、包括嵌套循环和if测试等。
为什么使用集合
集合操作有各种各样常见的用途,其中一些比数学更加实用。例如,由于项在集合中只能存储一次,集合(set)可以用来把重复项从其他集合(collection)中过滤掉。直接把集合(collection)转换为一个集合(set),然后再转换回来即可(因为集合是可迭代的,这里的list调用对其有效):
当你遍历图形或其他的回环结构的时候,集合可以用来记录已经访问过的位置。例如,我们将分别在第24章和第30章学习的传递性模块重载和继承树列表程序示例,必须确保访问过的项不再循环。尽管把访问状态作为键记录到字典中很高效,但集合提供了几乎等同的一种替代方式(并且可能更直观或更晦涩,取决你征求谁的意见)。
最后,在处理较大的数据集合的时候(例如,数据库查询结果),两个集合的交集包含了两个领域中共有的对象,并集包含了两个集合中的所有项目。为了说明,这里给出集合操作的一些实际例子,这些操作应用于一个假定公司的人员名单,使用Python 3.0集合常量(在Python 2.6中使用set):
在Python库手册以及关系数据库理论的一些相关资料中,我们可以找到关于集合操作的更多细节。在本书第8章中介绍Python 3.0中的字典视图对象的时候,我们将再次回顾这里所见到的一些集合操作。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论