阅读前,请先思考下列表、字典、元组、集合 之间的区别。什么场景下使用集合?
一个集合是一个无索引的、可变的、无重复的无序元素集合。集合用大括号{}
创建。例如:
my_set = {
"apple",
"banana",
"cherry"
}
创建集合set
用大括号{}
或者内置函数set()
创建集合。
代码:
my_set = {"apple", "banana", "cherry"}
print(my_set)
# 创建一个集合,可以使用大括号或者内置函数
my_set_2 = set(["one", "two", "three"]) # 将列表转为集合,自动去重
my_set_2 = set(("one", "two", "three")) # 将元组转为集合,自动去重
print(my_set_2)
my_set_3 = set("aaabbbcccdddeeeeeffff") # 将字符串转为集合,自动去重
print(my_set_3)
# 小心:一个空集合不能使用{},因为这会被解释为字典,用set()代替
a = {}
print(type(a)) # 此时为字典
a = set()
print(type(a))
结果:
{'banana', 'apple', 'cherry'}
{'three', 'one', 'two'}
{'b', 'c', 'd', 'e', 'f', 'a'}
<class 'dict'>
<class 'set'>
增加元素
调用set.add()
函数向集合中添加元素。
代码:
my_set = set()
# 用add()方法增加元素
my_set.add(42)
my_set.add(True)
my_set.add("Hello")
# 注意:添加的元素没有顺序,添加的元素可能会在打印时不同
print(my_set)
# 什么也不会发生,因为元素已经存在
my_set.add(42)
print(my_set)
结果:
{True, 42, 'Hello'}
{True, 42, 'Hello'}
移除元素
从集合中删除元素,如如下4种方法:
set.remove()
删除集合中的某个元素,元素不存在时抛出异常KeyError
。set.discard()
删除集合中的某个元素,元素不存在时不抛出异常。set.clear()
清空集合set.pop()
随机返回一个元素,并删除
代码:
# remove(x):移除x,如果元素不存在,则抛出KeyError异常
my_set = {"apple", "banana", "cherry"}
my_set.remove("apple")
print(my_set)
# KeyError:
# my_set.remove("orange")
# discard(x): 如果元素不存在,不会抛出异常
my_set.discard("cherry")
my_set.discard("blueberry")
print(my_set)
# clear():移除所有元素
my_set.clear()
print(my_set)
# pop(): 移除并返回一个随机元素
a = {True, 2, False, "hi", "hello"}
print(a.pop())
print(a)
结果:
{'banana', 'cherry'}
{'banana'}
set()
False
{True, 2, 'hi', 'hello'}
检查元素是否在
in
操作符,适合列表、字典、元组 及集合,万能的检查元素是否存在!
代码:
my_set = {"apple", "banana", "cherry"}
if "apple" in my_set:
print("yes")
结果:
yes
遍历集合
for
循环遍历,适合列表、字典、元组 及集合,万能遍历容器类数据结构!
代码:
# 迭代集合
# 注意:顺序不重要
my_set = {"apple", "banana", "cherry"}
for i in my_set:
print(i)
结果:
banana
apple
cherry
合并 和 交集
set_a.union(set_b)
返回集合set_a
与set_b
的并集,且不改变set_a
、set_b
set_a.intersection(set_b)
返回集合set_a
与set_b
的交集 ,且不改变set_a
、set_b
代码:
odds = {1, 3, 5, 7, 9}
evens = {0, 2, 4, 6, 8}
primes = {2, 3, 5, 7}
# union(): 合并两个集合,不会有重复
# 注意:这不会改变两个集合
u = odds.union(evens)
print(u)
# intersection(): 求交集
i = odds.intersection(evens)
print(i)
i = odds.intersection(primes)
print(i)
i = evens.intersection(primes)
print(i)
结果:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
set()
{3, 5, 7}
{2}
差集
set_a.difference(set_b)
返回集合set_a
中不在set_b
中的元素,即差集,且不改变set_a
、set_b
set_a.symmetric_difference(set_b)
返回set_
和set_b
中不同的元素
注意:
set_a.symmetric_difference(set_b)
=set_b.symmetric_difference(set_a)
想想为什么?
代码:
setA = {1, 2, 3, 4, 5, 6, 7, 8, 9}
setB = {1, 2, 3, 10, 11, 12}
# 差集:返回setA中不在setB中的元素
diff_set = setA.difference(setB)
print(diff_set)
# 反过来,返回setB中不在setA中的元素
diff_set = setB.difference(setA)
print(diff_set)
# symmetric_difference():返回setA和setB中不同的元素
diff_set = setA.symmetric_difference(setB)
print(diff_set)
# A.symmetric_difference(B) = B.symmetric_difference(A)
diff_set = setB.symmetric_difference(setA)
print(diff_set)
结果:
{4, 5, 6, 7, 8, 9}
{10, 11, 12}
{4, 5, 6, 7, 8, 9, 10, 11, 12}
{4, 5, 6, 7, 8, 9, 10, 11, 12}
更新集合
主要有update()
、intersection_update
、difference_update
、symmetric_difference_update
四种方法,具体见如下代码:
setA = {1, 2, 3, 4, 5, 6, 7, 8, 9}
setB = {1, 2, 3, 10, 11, 12}
# update(): 将setB中的元素添加到setA中
setA.update(setB)
print(setA)
# intersection_update(): 将setA和setB中的元素交集添加到setA中
setA = {1, 2, 3, 4, 5, 6, 7, 8, 9}
setA.intersection_update(setB)
print(setA)
# difference_update() : 将setA和setB中的元素差集添加到setA中
setA = {1, 2, 3, 4, 5, 6, 7, 8, 9}
setA.difference_update(setB)
print(setA)
# symmetric_difference_update(): 将setA和setB中的元素对称差集添加到setA中
setA = {1, 2, 3, 4, 5, 6, 7, 8, 9}
setA.symmetric_difference_update(setB)
print(setA)
# 注意:所有的update方法也可以用其他可迭代对象作为参数,如列表,元组
# setA.update([1, 2, 3, 4, 5, 6])
结果:
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
{1, 2, 3}
{4, 5, 6, 7, 8, 9}
{4, 5, 6, 7, 8, 9, 10, 11, 12}
复制
单纯=
赋值,只是引用,copy
则深度拷贝。
代码:
set_org = {1, 2, 3, 4, 5}
# 这只是复制了set的引用,所以要小心
set_copy = set_org
# 修改的复制也影响了原始的
set_copy.update([3, 4, 5, 6, 7])
print(set_copy)
print(set_org)
# 用copy()函数真正的复制集合
set_org = {1, 2, 3, 4, 5}
set_copy = set_org.copy()
# 现在修改的复制不会影响原始的
set_copy.update([3, 4, 5, 6, 7])
print(set_copy)
print(set_org)
结果:
{1, 2, 3, 4, 5, 6, 7}
{1, 2, 3, 4, 5, 6, 7}
{1, 2, 3, 4, 5, 6, 7}
{1, 2, 3, 4, 5}
子集,父集,不交集
set_a.issubset(set_b)
判断set_a
是否为set_b
的子集set_a.issuperset(set_b)
判断set_a
是否为set_b
的父集set_a.isdisjoint(set_b)
判断set_a
与set_b
是否有相同元素,无则返回True
。
思考:
set_a.issubset(set_b)
是否等同于set_b.issuperset(set_a)
?
setA = {1, 2, 3, 4, 5, 6}
setB = {1, 2, 3}
# issubset(setX): 如果setA是setB的子集,则返回True
print(setA.issubset(setB))
print(setB.issubset(setA)) # True
# 如果setA是setB的父集,则返回True
print(setA.issuperset(setB)) # True
print(setB.issuperset(setA))
# 如果两个集合没有相同的元素,则返回True
setC = {7, 8, 9}
print(setA.isdisjoint(setB))
print(setA.isdisjoint(setC))
结果:
False
True
True
False
False
True
冻结集合
冻结集只是普通集的不可变版本。 一般的,集合的元素可以随时修改,冻结后的元素保持不变。 创建:my_frozenset = freezeset(iterable)
代码:
a = frozenset([0, 1, 2, 3, 4])
# 下面的操作不允许
# a.add(5)
# a.remove(1)
# a.discard(1)
# a.clear()
# a.update([1,2,3])
# 其余的集合操作是可以的
odds = frozenset({1, 3, 5, 7, 9})
evens = frozenset({0, 2, 4, 6, 8})
print(odds.union(evens))
print(odds.intersection(evens))
print(odds.difference(evens))
结果:
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
frozenset()
frozenset({1, 3, 5, 7, 9})
小节
本文简要分享了集合set
的主要特性及相关内置方法,希望对你有所帮助。
欢迎大家点赞、收藏,支持!
pythontip 出品,Happy Coding!
公众号: 夸克编程