python进阶系列- 04 集合

阅读前,请先思考下列表、字典、元组、集合 之间的区别。什么场景下使用集合?

一个集合是一个无索引的、可变的、无重复的无序元素集合。集合用大括号{}创建。例如:

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_aset_b的并集,且不改变set_aset_b
  • set_a.intersection(set_b) 返回集合set_aset_b的交集 ,且不改变set_aset_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_aset_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_updatedifference_updatesymmetric_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_aset_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!

公众号: 夸克编程

猜你喜欢

转载自blog.csdn.net/pythontip/article/details/124159245
今日推荐