Python3 集合
集合(Set)是 Python 中的一种内置容器类型,用于存储多个不重复的元素。
集合具有以下特点:
- 元素不重复:相同的元素只会保留一份。
- 无序:元素没有固定的排列顺序,不支持通过索引访问。
- 元素必须可哈希:可以包含整数、字符串、元组等符合条件的对象,但不能直接包含列表、字典等不可哈希对象。
- 支持集合运算:可以进行并集、交集、差集、对称差集等操作。
- 可以修改:普通
set支持添加和删除元素。
集合常用于数据去重、成员判断以及多个数据集合之间的比较。
创建集合
可以使用大括号 {} 创建非空集合,元素之间使用逗号分隔,也可以使用 set() 从可迭代对象创建集合。
语法格式:
set_name = {value1, value2, value3}
set_name = set(iterable)
例如:
实例
set1 = {1, 2, 3, 4}
# 使用 set() 从列表创建集合
set2 = set([4, 5, 6, 7])
# 从字符串创建集合
set3 = set("hello")
print(sorted(set1))
print(sorted(set2))
print(sorted(set3))
执行结果:
[1, 2, 3, 4] [4, 5, 6, 7] ['e', 'h', 'l', 'o']
可以看到,set("hello") 自动去除了重复的字母 l。
注意:创建空集合必须使用 set(),不能使用 {},因为 {} 表示空字典。
empty_set = set() # 空集合
empty_dict = {} # 空字典
print(type(empty_set))
print(type(empty_dict))
执行结果:
<class 'set'> <class 'dict'>
集合自动去重
集合中的元素不会重复,因此可以利用 set() 对列表等可迭代对象进行去重。
实例
unique_numbers = set(numbers)
print(sorted(unique_numbers))
执行结果:
[1, 2, 3, 4, 5]
需要注意,转换为集合后,原有元素的排列顺序不会得到保证。
如果需要对列表去重并保留原有顺序,可以使用:
numbers = [3, 1, 2, 3, 2, 4] result = list(dict.fromkeys(numbers)) print(result)
执行结果:
[3, 1, 2, 4]
上述保序去重方法要求元素可以作为字典键使用,适用于 Python 3.7 及以上版本。
集合元素的类型限制
集合中的元素必须是可哈希(Hashable)的对象。
常见的可哈希对象包括整数、浮点数、字符串,以及所有成员都可哈希的元组。
my_set = {1, 3.14, "Python", (1, 2)}
print(len(my_set))
执行结果:
4
列表、字典和普通集合通常不可哈希,不能直接作为集合元素。
my_set = {[1, 2], [3, 4]}
# TypeError: unhashable type: 'list'
如果需要将一个集合作为另一个集合的元素,可以使用不可变集合 frozenset。
集合运算
Python 集合支持数学中常见的集合运算,例如并集、交集、差集和对称差集。
假设有两个集合:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
常见运算符如下:
| 运算 | 运算符 | 方法 | 说明 |
|---|---|---|---|
| 并集 | | |
union() |
两个集合中的所有元素,去除重复项 |
| 交集 | & |
intersection() |
同时属于两个集合的元素 |
| 差集 | - |
difference() |
属于第一个集合,但不属于第二个集合的元素 |
| 对称差集 | ^ |
symmetric_difference() |
只属于其中一个集合的元素 |
实例
b = {3, 4, 5, 6}
# 并集
print("并集:", sorted(a | b))
# 交集
print("交集:", sorted(a & b))
# 差集
print("差集:", sorted(a - b))
# 对称差集
print("对称差集:", sorted(a ^ b))
执行结果:
并集: [1, 2, 3, 4, 5, 6] 交集: [3, 4] 差集: [1, 2] 对称差集: [1, 2, 5, 6]
说明:差集具有方向性,a - b 与 b - a 的结果通常不同。
除了运算符,还可以使用集合方法:
a.union(b) a.intersection(b) a.difference(b) a.symmetric_difference(b)
这些方法返回新的集合,不会直接修改原集合。
集合运算符通常要求两个操作数是集合类型;对应的方法则可以根据具体方法接受列表、元组等可迭代对象。
集合推导式
与列表推导式类似,Python 也支持集合推导式(Set Comprehension),可以使用简洁的语法创建集合。
基本语法:
{expression for item in iterable if condition}
其中,if condition 是可选条件。
实例
squares = {x * x for x in range(1, 6)}
print(sorted(squares))
# 过滤字符串中的指定字符
letters = {
x for x in "abracadabra"
if x not in "abc"
}
print(sorted(letters))
执行结果:
[1, 4, 9, 16, 25] ['d', 'r']
集合推导式也会自动去除重复元素。
集合的基本操作
1、添加元素
可以使用 add() 方法向集合添加一个元素。
语法格式:
s.add(x)
如果元素已经存在,集合不会发生变化,也不会报错。
实例
thisset.add("Facebook")
thisset.add("Google") # 已存在,不会重复添加
print(sorted(thisset))
执行结果:
['Facebook', 'Google', 'Runoob', 'Taobao']
如果需要一次添加多个元素,可以使用 update()。
语法格式:
s.update(iterable1, iterable2, ...)
update() 可以接收一个或多个可迭代对象,将其中的元素加入当前集合。
实例
# 添加列表中的元素
thisset.update([4, 5])
# 同时添加多个可迭代对象中的元素
thisset.update((6, 7), {8, 9})
print(sorted(thisset))
执行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
注意:如果向 update() 传入字典,添加的是字典的键,而不是值。
s = {1, 2}
s.update({"a": 10, "b": 20})
print(sorted(s, key=str))
输出结果:
[1, 2, 'a', 'b']
如果想添加字典的值,可以使用 dict.values(),前提是这些值可以作为集合元素。
2、移除元素
集合提供了 remove()、discard() 和 pop() 等删除方法。
remove() 方法
remove() 用于删除指定元素。如果元素不存在,会抛出 KeyError 异常。
语法格式:
s.remove(x)
实例
thisset.remove("Taobao")
print(sorted(thisset))
# 以下操作会引发 KeyError
thisset.remove("Facebook")
执行结果:
['Google', 'Runoob'] Traceback (most recent call last): ... KeyError: 'Facebook'
discard() 方法
discard() 同样用于删除指定元素,但如果元素不存在,不会抛出异常。
语法格式:
s.discard(x)
实例
thisset.discard("Facebook") # 不存在,不报错
thisset.discard("Taobao")
print(sorted(thisset))
执行结果:
['Google', 'Runoob']
pop() 方法
pop() 用于从集合中移除并返回一个任意元素。
语法格式:
s.pop()
实例
# 移除一个元素
removed = thisset.pop()
print("移除的元素属于原集合:",
removed in {"Google", "Runoob", "Taobao", "Facebook"})
print("剩余元素个数:", len(thisset))
执行结果:
移除的元素属于原集合: True 剩余元素个数: 3
注意:pop() 并不是随机抽样函数,也不是删除集合中的第一个元素。集合没有固定顺序,因此不能预测它会返回哪个元素。
如果集合为空,调用 pop() 会抛出 KeyError 异常。
删除方法对比
| 方法 | 作用 | 元素不存在时 |
|---|---|---|
remove(x) |
删除指定元素 | 抛出 KeyError |
discard(x) |
删除指定元素 | 不报错 |
pop() |
移除并返回任意元素 | 空集合会抛出 KeyError |
3、计算集合元素个数
可以使用 len() 函数获取集合中的元素数量。
语法格式:
len(s)
实例
print(len(thisset))
thisset.add("Google")
print(len(thisset))
执行结果:
3 3
因为集合不会保存重复元素,所以再次添加 "Google" 后,元素个数不变。
4、清空集合
可以使用 clear() 方法删除集合中的所有元素。
语法格式:
s.clear()
实例
thisset.clear()
print(thisset)
print(len(thisset))
执行结果:
set() 0
这里输出的 set() 表示一个空集合。
5、判断元素是否在集合中
可以使用 in 和 not in 运算符判断元素是否属于集合。
语法格式:
x in s x not in s
实例
print("Runoob" in thisset)
print("Facebook" in thisset)
print("Facebook" not in thisset)
执行结果:
True False True
集合通常基于哈希表实现,因此成员判断在一般情况下具有较高效率,平均时间复杂度通常为 O(1),但最坏情况下可能退化。
6、判断子集、超集和不相交集合
除了并集、交集等运算,Python 还支持判断两个集合之间的包含关系。
常见方法如下:
| 方法 | 作用 |
|---|---|
issubset() |
判断当前集合是否为指定集合的子集 |
issuperset() |
判断当前集合是否包含指定集合的全部元素 |
isdisjoint() |
判断两个集合是否没有公共元素 |
实例
b = {1, 2, 3, 4}
c = {5, 6}
print(a.issubset(b))
print(b.issuperset(a))
print(a.isdisjoint(c))
# 也可以使用比较运算符
print(a <= b) # 子集
print(a < b) # 真子集
print(b >= a) # 超集
执行结果:
True True True True True True
<= 和 >= 允许两个集合相等;< 和 > 则分别表示真子集和真超集,要求两者不相等。
不可变集合 frozenset
除了普通集合 set,Python 还提供不可变集合 frozenset。
两者都具有元素不重复、无固定顺序等特点,但 frozenset 创建后不能添加或删除元素。
可以使用 frozenset() 创建不可变集合。
实例
print(sorted(a))
print(type(a))
# frozenset 支持集合运算
b = frozenset([3, 4, 5])
print(sorted(a | b))
print(sorted(a & b))
执行结果:
[1, 2, 3] <class 'frozenset'> [1, 2, 3, 4, 5] [3]
frozenset 不支持 add()、remove()、update() 等修改方法。
由于 frozenset 本身可以作为可哈希对象使用,因此也可以将它作为其他集合的元素。
nested_set = {
frozenset({1, 2}),
frozenset({3, 4})
}
print(len(nested_set))
执行结果:
2
普通的 set 不能直接作为另一个集合的元素,但 frozenset 可以。
集合使用注意事项
在使用 Python 集合时,需要注意以下几点:
- 集合没有固定顺序:不要依赖
print(set)的元素排列结果,也不要通过下标访问集合。 - 元素不能重复:重复添加相同元素不会增加集合大小。
- 元素必须可哈希:列表、字典等不可哈希对象不能直接作为集合元素。
- set() 可以接收可迭代对象:例如字符串、列表、元组;传入字典时使用的是字典的键。
- 集合可以遍历:可以通过
for循环访问元素,但遍历顺序不应作为业务依据。 - 集合不支持索引和切片:不能使用
s[0]或s[1:3]。 - 注意相等性:例如
True和1在集合中会被视为相等的元素,不能分别作为两个不同元素保存。
如果需要将集合中的元素按固定顺序显示,可以使用 sorted()。但如果集合包含无法相互比较的混合类型,直接排序可能引发 TypeError。
集合内置方法完整列表
以下整理了 Python 集合常用的内置方法。
| 方法 | 描述 |
|---|---|
| add() | 向集合添加一个元素,已存在则不做修改。 |
| clear() | 移除集合中的所有元素。 |
| copy() | 返回集合的浅拷贝。 |
| difference() | 返回差集,不修改原集合。 |
| difference_update() | 直接修改当前集合,移除同时存在于其他可迭代对象中的元素。 |
| discard() | 移除指定元素,元素不存在时不报错。 |
| intersection() | 返回交集,不修改原集合。 |
| intersection_update() | 直接修改当前集合,只保留与指定可迭代对象共有的元素。 |
| isdisjoint() | 判断两个集合是否没有公共元素。 |
| issubset() | 判断当前集合是否为指定集合的子集。 |
| issuperset() | 判断当前集合是否为指定集合的超集。 |
| pop() | 移除并返回一个任意元素,空集合会抛出 KeyError。 |
| remove() | 移除指定元素,元素不存在时抛出 KeyError。 |
| symmetric_difference() | 返回对称差集,即只存在于两个集合之一的元素。 |
| symmetric_difference_update() | 直接修改当前集合,使其只保留原集合与指定集合中非共有的元素。 |
| union() | 返回并集,不修改原集合。 |
| update() | 将一个或多个可迭代对象中的元素加入当前集合。 |
| len() | 内置函数,返回集合的元素个数。 |
注意:len() 是 Python 的内置函数,并非 set 对象自身的方法。
另外,以 _update() 结尾的集合方法通常直接修改原集合,并返回 None;而 union()、intersection() 等方法会返回新的集合。
总结
Python 集合主要用于存储不重复的数据,并支持高效的成员判断和常见集合运算。
在实际开发中,集合最常见的用途包括:
- 对列表中的重复数据进行去重。
- 判断某个元素是否存在。
- 求两个数据集合的交集、并集和差集。
- 比较两个集合之间的包含关系。
- 使用
frozenset保存不需要修改的集合。
如果需要按照索引访问数据,或者需要保留元素的插入顺序,通常应该优先考虑列表等其他数据结构;如果需要去重、集合运算或快速成员判断,则可以优先考虑集合。
Nine
dai***0@126.com
s.update( "字符串" ) 与 s.update( {"字符串"} ) 含义不同:
>>> thisset = set(("Google", "Runoob", "Taobao")) >>> print(thisset) {'Google', 'Runoob', 'Taobao'} >>> thisset.update({"Facebook"}) >>> print(thisset) {'Google', 'Runoob', 'Taobao', 'Facebook'} >>> thisset.update("Yahoo") >>> print(thisset) {'h', 'o', 'Facebook', 'Google', 'Y', 'Runoob', 'Taobao', 'a'} >>>Nine
dai***0@126.com
yijiarenppaa
122***9964@qq.com
set() 中参数注意事项
1.创建一个含有一个元素的集合
>>> my_set = set(('apple',)) >>> my_set {'apple'}2.创建一个含有多个元素的集合
>>> my_set = set(('apple','pear','banana')) >>> my_set {'apple', 'banana', 'pear'}3.如无必要,不要写成如下形式
>>> my_set = set('apple') >>> my_set {'l', 'e', 'p', 'a'} >>> my_set1 = set(('apple')) >>> my_set1 {'l', 'e', 'p', 'a'}yijiarenppaa
122***9964@qq.com
Steven Tse
359***491@qq.com
参考地址
集合用 set.pop() 方法删除元素的不一样的感想如下:
1、对于 python 中列表 list、tuple 类型中的元素,转换集合是,会去掉重复的元素如下:
>>> list = [1,1,2,3,4,5,3,1,4,6,5] >>> set(list) {1, 2, 3, 4, 5, 6} >>> tuple = (2,3,5,6,3,5,2,5) >>> set(tuple) {2, 3, 5, 6}2、集合对 list 和 tuple 具有排序(升序),举例如下:
>>> set([9,4,5,2,6,7,1,8]) {1, 2, 4, 5, 6, 7, 8, 9} >>> set([9,4,5,2,6,7,1,8]) {1, 2, 4, 5, 6, 7, 8, 9}3、集合的 set.pop() 的不同认为
有人认为 set.pop() 是随机删除集合中的一个元素、我在这里说句非也!对于是字典和字符转换的集合是随机删除元素的。当集合是由列表和元组组成时、set.pop() 是从左边删除元素的如下:
列表实例:
输出结果:
{1, 2, 4, 5, 6, 7, 8, 9} 1 {2, 4, 5, 6, 7, 8, 9}元组实例:
输出结果:
{0, 1, 2, 3, 6, 7, 8, 9} 0 {1, 2, 3, 6, 7, 8, 9}Steven Tse
359***491@qq.com
参考地址
Sililililidary
282***7697@qq.com
>>> thisset = set(("Google", "Runoob", "Taobao", "Facebook")) >>> y=set({'python'}) >>> print(y.union(thisset)) {'python', 'Taobao', 'Google', 'Facebook', 'Runoob'}输出结果:
{'python', 'Google', 'Taobao', 'Facebook', 'Runoob'}y 的集合里此时只含有一个元素 'python',而如果不加花括号时,y 的集合里含有'p','y','t','h','o','n'五个元素。
>>> thisset = set(("Google", "Runoob", "Taobao", "Facebook")) >>> y=set('python') >>> print(y.union(thisset)) {'p', 'o', 'y', 'Taobao', 'h', 'Google', 'Facebook', 'Runoob', 'n', 't'}也可以使用括号:
thisset = set(("Google", "Runoob", "Taobao", "Facebook")) y=set(('python','love')) print(y.union(thisset))输出结果:
{'Facebook', 'Runoob', 'Taobao', 'python', 'love', 'Google'}但是当 y 的集合里只有一个字符串时,结果与不加花括号一样。
Sililililidary
282***7697@qq.com
qinjeremy
qin***emy@msn.com
列表的 sort 方法可以实现就地排序(无需创建新对象,字符串按首字母进行排序):
输出:
按集合中的字符长度进行排序:
输出:
qinjeremy
qin***emy@msn.com
vipkwd
ser***e@vipkwd.com
本课一句话通俗话总结函数:
添加元素
删除元素
右全包含布尔真:判断 setx 集合的所有元素是否都包含在 sety 集合中
setx.issubset(sety):bool >>> x = {"a", "b", "c"} >>> y = {"f", "e", "d", "c", "b", "a"} >>> x.issubset(y) True左全包含布尔真: 判断 sety 集合的所有元素是否都包含在原始 setx 的集合中
setx.issuperset(sety):bool >>> x = {"a", "b", "c"} >>> y = {"f", "e", "d", "c", "b", "a"} >>> y.issuperset(x) True右半包含布尔取反:判断集合 sety 中是否有集合 setx 的任一元素(包含返回 False,不包含返回 True)
合并集合(并集):(注意:集合元素的去重、唯一性)
setx.union(sety [, setz...]):set >>> x = {"a", "b", "c"} >>> y = {"f", "d", "a"} >>> z = {"c", "d", "e"} >>> x.union(y, z) {'c', 'd', 'f', 'e', 'b', 'a'}左包含差集: 返回集合的差集,即返回的集合元素包含在第一个集合 x 中,但不包含在第二个集合 y(方法的参数)中
左引用删除交集(无返回值,即直接修改原内存指向)
>>> x,y ({'banana', 'cshit', 'vipkwd.com', 'alipay'}, {'google', 'runoob', 'facebook', 'alipay'})>>> type(x.difference_update(y)) <class 'NoneType'> >>> x,y ({'banana', 'cshit', 'vipkwd.com'}, {'google', 'runoob', 'facebook', 'alipay'})左右差集:返回两个集合中不重复的元素集合,即会移除两个集合中都存在的元素
左引用删除交集且引用追加右差集(引用操作,无返回值)
左右交集:返回两个或更多集合中都包含的元素,即交集
左引用交集
辅助理解:所有提到 “引用” 俩字的都是函数内部直接操作内存指向,故无返回值;反之:如果一个函数没有实质返回值,那么它一定是在函数内部改变了其他位置内容, 否则这个函数就是 dog shit,因为它不具有实质的意义。
vipkwd
ser***e@vipkwd.com