6.1  基本概念

Python语言中的集合是无序的、可变的容器类对象,所有元素放在一对大括号中,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,不允许重复。

集合中只能包含数字、字符串、元组等不可变类型或可哈希的数据,不能包含列表、字典、集合等可变类型或不可哈希的数据,包含列表等可变类型数据的元组也不能作为集合的元素。

集合中的元素是无序的,元素存储顺序和添加顺序并不一致,先放入集合的元素不一定存储在前面。集合中的元素不存在“位置”或“索引”的概念,不支持使用下标直接访问指定位置上的元素,不支持使用切片访问其中的元素,也不支持使用random中的choice()函数从集合中随机选取元素,但支持使用random模块中的sample()函数随机选取部分元素。

6.2  集合创建与删除

除了把若干可哈希对象放在一对大括号内创建集合,也可以使用set()函数将列表、元组、字符串、range对象等其他可迭代对象转换为集合,如果原来的数据中存在重复元素,在转换为集合的时候只保留一个,自动去除重复元素。如果原序列或可迭代对象中有可变类型的数据,无法转换成为集合,抛出TypeError异常并提示对象不可哈希。当不再使用某个集合时,可以使用del语句删除整个集合。下面的代码演示了创建集合的不同形式和方法。

一文掌握Python集合的语法与应用_Python

6.3  集合常用方法

Python内置集合类set支持内置函数len()、max()、min()、sum()、sorted()、map()、filter()、enumerate()、all()、any()等内置函数和并集运算符“|”、交集运算符“&”、差集运算符“-”、对称差集运算符“^”、成员测试运算符“in”、同一性测试运算符“is”,不支持内置函数reversed(),相关内置函数的介绍详见本书第2章。另外,set类自身还提供了大量方法,如表6-1所示。

表6-1  Python内置集合类提供的方法

方法

功能简介

add(...)

往当前集合中增加一个可哈希元素,如果集合中已经存在该元素,直接忽略该操作,如果参数不可哈希,抛出TypeError异常并提示参数不可哈希。该方法没有返回值

clear()

删除当前集合对象中所有元素,没有返回值

copy()

返回当前集合对象的浅复制

difference(...)

接收一个或多个集合(或其他可迭代对象),返回当前集合对象与所有参数对象的差集,功能类似于差集运算符-

difference_update(...)

接收一个或多个集合(或其他可迭代对象),从当前集合中删除所有参数对象中的元素,对当前集合进行更新,该方法没有返回值,功能类似于运算符-=

discard(...)

接收一个可哈希对象作为参数,从当前集合中删除该元素,如果参数元素不在当前集合中则直接忽略该操作。该方法没有返回值

intersection(...)

接收一个或多个集合对象(或其他可迭代对象),返回当前集合与所有参数对象的交集,功能类似于交集运算符&

intersection_update(...)

接收一个或多个集合(或其他可迭代对象),使用当前集合与所有参数对象的交集更新当前集合对象,功能类似于运算符&=

isdisjoint(...)

接收一个集合(或其他可迭代对象),如果当前集合与参数对象的交集为空则返回True

issubset(...)

接收一个集合(或其他可迭代对象),测试当前集合是否为参数对象的子集,是则返回True,否则返回False,等价于关系运算符<=

issuperset(...)

接收一个集合(或其他可迭代对象),测试当前集合是否为参数对象的超集,是则返回True,否则返回False,等价于关系运算符>=

pop()

不接收参数,删除并返回当前集合中的任意一个元素,如果当前集合为空则抛出KeyError异常

remove(...)

从当前集合中删除一个元素,如果参数指定的元素不在集合中,抛出KeyError异常

symmetric_difference(...)

接收一个集合(或其他可迭代对象),返回当前集合与参数对象的对称差集,等价于对称差集运算符^

symmetric_difference_update(...)

接收一个集合(或其他可迭代对象),使用当前集合与参数对象的对称差集更新当前集合,等价于运算符^=

union(...)

接收一个或多个集合(或其他可迭代对象),返回当前集合与所有参数对象的并集,功能类似于并集运算符|

update(...)

接收一个或多个集合(或其他可迭代对象),把参数对象中所有元素添加到当前集合对象中,没有返回值

6.3.1  原地增加/删除集合元素

集合方法add()、update()可以用于向集合中添加新元素,difference_update()、intersection_update()、pop()、remove()、symmetric_difference_update()、clear()可以用于删除集合中的元素,这些方法都是对集合对象原地进行修改。下面的代码演示了部分方法的用法。

一文掌握Python集合的语法与应用_Python_02

6.3.2  计算交集/并集/差集/对称差集返回新集合

集合方法difference()、intersection()、union()分别用来返回当前集合与另外一个或多个集合(或其他可迭代对象)的差集、交集、并集,方法symmetric_difference()用来返回当前集合与另外一个集合(或其他可迭代对象)的对称差集。下面的代码演示了这几个方法的用法。

一文掌握Python集合的语法与应用_Python_03

6.3.3  集合测试

集合方法issubset()、issuperset()、isdisjoint()分别用来测试当前集合是否为另一个集合的子集、是否为另一个集合的超集、是否与另一个集合不相邻(或交集是否为空)。下面的代码演示了这几个方法的用法。

一文掌握Python集合的语法与应用_运算符_04

6.4  综合例题解析

例6-1  编写程序,求解买啤酒问题。一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升、32升、36升、40升和62升,并且只卖整桶酒,不零卖。第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的2倍。计算有多少升啤酒。

解析:逐个遍历每一桶并假设是啤酒,从剩余几桶中任选两桶并假设是第一位顾客购买的葡萄酒的数量,如果这两桶啤酒恰好是剩余几桶总容量的三分之一,说明本次假设的啤酒是正确的。

一文掌握Python集合的语法与应用_运算符_05

例6-2  编写程序,输入包含任意数据的列表,检查列表中数据的重复情况。如果列表内所有元素都是一样的,输出“完全重复”;如果列表内所有元素都互相不一样,输出“完全不重复”;否则输出“部分重复”。

解析:利用集合能够自动去除重复的特点,把列表转换为集合,然后比较列表和集合的长度。如果二者相等,表示原列表中的数据无重复;如果转换为集合后只有一个元素,表示原列表中的数据是完全重复的;如果转换为集合后数据数量减少但没有减少为1,说明原列表中的数据有一部分是重复的。

一文掌握Python集合的语法与应用_迭代_06

一文掌握Python集合的语法与应用_运算符_07

一文掌握Python集合的语法与应用_迭代_08

一文掌握Python集合的语法与应用_迭代_09