当前位置: 首页 > news >正文

【Python】集合

目录

  • 集合
    • 集合基本概念
    • 创建集合
    • 访问集合项目
    • 添加集合项目
    • 删除集合项
    • 循环集合
    • 连接集合
    • 复制集合
    • 集合运算符
    • 集合方法
    • 冻结集合

集合

集合基本概念

什么是集合(Set)?

  • 集合 是一种 无序、可迭代、元素唯一 的数据结构。
  • 集合的底层是用 哈希表(hash table) 实现的。
  • 和数学集合类似,可以进行 交集、并集、差集、对称差集 等运算。

基本特性

  1. 无序:集合中的元素没有顺序,不能通过下标访问。
  2. 唯一性:集合中不会出现重复元素。
  3. 可变性:集合本身是可变的(可以添加、删除元素),但元素必须是 不可变对象(比如 int、str、tuple 可以,list、dict 不行)。

创建集合

创建空集合

注意:{} 默认是字典,要创建空集合必须用 set()

s = set()
print(s)         # set()
print(type(s))   # <class 'set'>

使用花括号 {} 创建集合

s = {1, 2, 3}
print(s)  # {1, 2, 3}

特点:

  • 元素 自动去重
s = {1, 2, 2, 3, 1}
print(s)  # {1, 2, 3}
  • 元素必须是 可哈希类型(int、str、tuple 可以,list、dict 不行)
s = {1, "abc", (1, 2)}
print(s)  # {1, (1, 2), 'abc'}# ❌ 错误示例:
s = {[1, 2], 3}
# TypeError: unhashable type: 'list'

使用 set(iterable) 创建

几乎任何 可迭代对象 都能转成集合。

从列表创建

s = set([1, 2, 2, 3])
print(s)  # {1, 2, 3}

从元组创建

s = set((1, 2, 3, 2))
print(s)  # {1, 2, 3}

从字符串创建

s = set("hello")
print(s)  # {'h', 'e', 'l', 'o'}

从字典创建,默认只会取 字典的 key

d = {"a": 1, "b": 2}
s = set(d)
print(s)  # {'a', 'b'}

使用集合推导式(Set Comprehension)

类似列表推导式,但用花括号 {}

s = {x**2 for x in range(5)}
print(s)  # {0, 1, 4, 9, 16}

可以加条件:

s = {x for x in range(10) if x % 2 == 0}
print(s)  # {0, 2, 4, 6, 8}

从其他集合复制

s1 = {1, 2, 3}
s2 = set(s1)       # 拷贝方式1
s3 = s1.copy()     # 拷贝方式2print(s2, s3)  # {1, 2, 3} {1, 2, 3}

创建不可变集合:frozenset

如果你不希望集合被修改,可以用 frozenset

fs = frozenset([1, 2, 3])
print(fs)  # frozenset({1, 2, 3})# ❌ 不能修改
# fs.add(4) -> AttributeError: 'frozenset' object has no attribute 'add'

创建大集合(性能优化)

  • 对大规模数据,直接用 set() 比逐个 add() 更快。
nums = range(1000000)
s = set(nums)  # ✅ 更快
  • 推导式方式也很常用:
s = {i for i in range(1000000)}  # 速度也很快

对比表

创建方式示例特点
空集合set(){} 会变成字典
直接字面量{1, 2, 3}简洁,常用
通过 set()set([1, 2, 3])可从任意可迭代对象
推导式{x**2 for x in range(5)}灵活,可加条件
拷贝set(s1) / s1.copy()复制已有集合
不可变集合frozenset([1, 2])可作为字典 key

访问集合项目

集合访问的基本概念

  • 集合(set) 是无序、唯一元素的容器。
  • 不能通过索引或键访问(不像列表用 list[0] 或字典用 dict['key'])。
  • 访问集合的元素主要依靠:
    1. 迭代(for 循环、推导式)
    2. 成员运算符(in / not in)
    3. 集合运算(子集、交集等)

使用 for 循环访问集合元素

集合是可迭代对象,可以直接用 for 循环遍历:

langs = {"C", "C++", "Java", "Python"}for lang in langs:print(lang)

可能输出(注意集合无序,每次顺序可能不同):

Python
C
C++
Java

要点:

  • 无序性:访问顺序不确定。
  • 唯一性:不会有重复元素。

使用推导式访问集合元素

推导式提供了一种简洁的写法,可以在访问时直接做操作。

my_set = {1, 2, 3, 4, 5}
squares = [x**2 for x in my_set]  # 转成列表
print(squares)

输出:

[1, 4, 9, 16, 25]

也可以生成 新的集合

evens = {x for x in my_set if x % 2 == 0}
print(evens)  # {2, 4}

检查集合中是否存在某元素

innot in 运算符:

langs = {"C", "C++", "Java", "Python"}# 检查元素是否存在
if "Java" in langs:print("Java is present in the set.")# 检查元素是否不存在
if "SQL" not in langs:print("SQL is not present in the set.")

输出:

Java is present in the set.
SQL is not present in the set.

复杂度:集合查找平均时间复杂度是 O(1),比列表快很多。

从集合访问子集(Subset)

  1. 判断一个集合是否是另一个集合的子集

    original_set = {1, 2, 3, 4}
    print({1, 2}.issubset(original_set))  # True
    print({1, 5}.issubset(original_set))  # False
    
  2. 判断超集

    print(original_set.issuperset({1, 2}))  # True
    
  3. 使用 itertools 生成所有子集(幂集)

    import itertoolsoriginal_set = {1, 2, 3, 4}# 所有包含两个元素的子集
    subsets_with_two_elements = [set(subset) for subset in itertools.combinations(original_set, 2)]
    print(subsets_with_two_elements)
    

    输出:

    [{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}]
    

转换集合以访问元素

有时需要“伪索引”访问,可以先转换为列表/元组:

s = {"apple", "banana", "cherry"}
lst = list(s)
print(lst[0])   # 可以索引访问

缺点:转换后 顺序仍不固定(集合本身无序)。

访问集合时的运算

集合访问不仅限于迭代,还常结合数学运算使用。

交集(访问共同元素)

a = {"Python", "Java", "C++"}
b = {"Python", "Rust"}
print(a & b)  # {'Python'}

差集(访问独有元素)

print(a - b)  # {'Java', 'C++'}

对称差集(只在一个集合中的元素)

print(a ^ b)  # {'Java', 'C++', 'Rust'}

集合访问的核心方式

方式示例适用场景
for 循环for x in s: print(x)遍历集合
推导式[x**2 for x in s]一边访问一边生成结果
成员运算符if x in s快速查找元素
子集关系a.issubset(b)判断集合关系
幂集生成itertools.combinations枚举子集
转换为列表list(s)[0]临时索引访问

添加集合项目

基础概念

  • 集合是可变的 → 可以随时添加元素。
  • 集合中的元素必须是不可变的对象(如 intstrtuple),不能是 listdict、另一个 set
  • 添加元素时自动去重:重复元素不会被插入。

使用 add() 添加单个元素

语法

set.add(element)
  • 只能添加 一个元素
  • 如果元素已存在,集合不变。

示例

language = set()language.add("C")
language.add("C++")
language.add("Java")
language.add("Python")
language.add("Python")   # 重复添加不会报错,但不会插入print("Updated Set:", language)

可能输出(无序):

Updated Set: {'Python', 'Java', 'C++', 'C'}

注意

s = set()
s.add([1, 2])   # ❌ 报错:list是可变的,不能作为集合元素
s.add((1, 2))   # ✅ tuple是不可变的,可以添加

使用 update() 添加多个元素

语法

set.update(iterable)
  • 接受任意可迭代对象(列表、元组、字符串、集合等)。
  • 可一次性插入多个元素。

示例 1:添加单个可迭代对象

my_set = {1, 2, 3}
my_set.update([4])
print("Updated Set:", my_set)

输出:

Updated Set: {1, 2, 3, 4}

示例 2:添加多个集合

lang1 = {"C", "C++", "Java", "Python"}
lang2 = {"PHP", "C#", "Perl"}
lang1.update(lang2)
print(lang1)

输出:

{'Python', 'C++', 'C#', 'C', 'Java', 'PHP', 'Perl'}

示例 3:字符串被当作字符集合

set1 = set("Hello")
set1.update("World")
print(set1)

输出(无序):

{'H', 'r', 'o', 'd', 'W', 'l', 'e'}

使用集合运算 union() / |

语法

set1.union(set2, ...)
set1 | set2 | ...
  • 返回 新集合,不修改原集合。
  • 合并多个集合/可迭代对象,自动去重。

示例

lang1 = {"C", "C++", "Java", "Python"}
lang2 = {"PHP", "C#", "Perl"}
lang3 = {"SQL", "C#"}combined_set1 = lang1.union(lang2)  
combined_set2 = lang2 | lang3  print("Combined Set1:", combined_set1)
print("Combined Set2:", combined_set2)

输出:

Combined Set1: {'C#', 'Perl', 'C++', 'Java', 'PHP', 'Python', 'C'}
Combined Set2: {'C#', 'Perl', 'PHP', 'SQL'}

示例:union 接收序列

lang1 = {"C", "C++", "Java", "Python"}
lang2 = ["PHP", "C#", "Perl"]
lang3 = lang1.union(lang2)
print(lang3)

输出:

{'PHP', 'C#', 'Python', 'C', 'Java', 'C++', 'Perl'}

使用 集合推导式(Set Comprehension)

  • 一种 声明式写法,用来快速生成新集合。
  • 适合根据已有数据 批量添加处理后的元素

示例 1:生成平方数集合

numbers = [1, 2, 3, 4, 5]
squares_set = {num ** 2 for num in numbers}
print("Squares Set:", squares_set)

输出:

Squares Set: {1, 4, 9, 16, 25}

示例 2:过滤条件

numbers = [1, 2, 3, 4, 5, 6]
evens = {num for num in numbers if num % 2 == 0}
print("Even Set:", evens)

输出:

Even Set: {2, 4, 6}

添加集合元素的方式

方法是否修改原集合适用场景
add()添加单个元素
update()批量添加多个元素(来自列表/元组/字符串/集合)
union()❌(返回新集合)合并多个集合/序列,保持原集合不变
`` 运算符❌(返回新集合)
集合推导式 {expr for ...}❌(返回新集合)批量生成新集合,支持条件过滤

删除集合项

Python 集合(set)是 无序、可变、唯一元素的集合。删除元素的方法非常丰富,不同方法适合不同场景。

remove() 方法 —— 删除指定元素(若不存在报错)

语法:

set.remove(element)

特点:

  • 删除指定元素;
  • 若元素不存在 → KeyError

示例:

my_set = {"Rohan", "Physics", 21, 69.75}
print("Original:", my_set)my_set.remove("Physics")   # 删除存在的元素
print("After remove:", my_set)my_set.remove("PHP")       # 删除不存在的元素 → 报错

输出:

Original: {21, 69.75, 'Rohan', 'Physics'}
After remove: {21, 69.75, 'Rohan'}
KeyError: 'PHP'

discard() 方法 —— 删除指定元素(若不存在不报错)

语法:

set.discard(element)

特点:

  • 删除指定元素;
  • 元素不存在时 不会报错

示例:

my_set = {"Rohan", "Physics", 21, 69.75}
print("Original:", my_set)my_set.discard("Physics")  # 删除存在的元素
print("After discard:", my_set)my_set.discard("PHP")      # 删除不存在的元素,不报错
print("After discard non-existent:", my_set)

pop() 方法 —— 删除并返回一个随机元素

语法:

removed = set.pop()

特点:

  • 删除集合中 任意元素
  • 集合为空时 → KeyError

示例:

my_set = {1, 2, 3, 4, 5}
removed = my_set.pop()
print("Removed:", removed)
print("Updated:", my_set)empty_set = set()
empty_set.pop()   # ❌ 报错 KeyError

clear() 方法 —— 清空集合

语法:

set.clear()

特点: 删除集合中所有元素,集合变为空。

示例:

my_set = {1, 2, 3, 4, 5}
my_set.clear()
print("After clear:", my_set)   # set()

difference_update() —— 删除两个集合的交集

语法:

set1.difference_update(set2)

特点:set1 中删除 set2 里也存在的元素。

示例:

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7}
s1.difference_update(s2)
print(s1)   # {1, 2, 3}

intersection_update() —— 只保留交集

语法:

set1.intersection_update(set2)

特点: 删除不常见的元素,保留两者共有的。

示例:

set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set1.intersection_update(set2)
print(set1)   # {3, 4}

symmetric_difference_update() —— 删除交集,保留不相同的

语法:

set1.symmetric_difference_update(set2)

特点: 更新集合,使其只保留两者不相同的部分。

示例:

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7}
s1.symmetric_difference_update(s2)
print(s1)   # {1, 2, 3, 6, 7}

intersection() / symmetric_difference() —— 返回新集合

语法:

s3 = set1.intersection(set2)                # 返回交集
s4 = set1.symmetric_difference(set2)        # 返回对称差

特点: 不修改原集合,生成新集合。

示例:

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7}print(s1.intersection(s2))         # {4, 5}
print(s1.symmetric_difference(s2)) # {1, 2, 3, 6, 7}

集合推导式(Set Comprehension)—— 按条件删除元素

语法:

new_set = {expr for elem in old_set if condition}

特点: 生成新集合,可实现“删除符合条件的元素”。

示例:

numbers = {1, 2, 3, 4, 5, 6}
# 删除偶数,保留奇数
filtered = {n for n in numbers if n % 2 != 0}
print(filtered)   # {1, 3, 5}

对比表

方法是否报错是否修改原集合删除规则
remove(x)❌ KeyError删除指定元素
discard(x)✅ 安全删除指定元素
pop()❌ KeyError删除任意元素
clear()清空集合
difference_update()删除交集
intersection_update()只保留交集
symmetric_difference_update()删除交集,保留不相同
intersection()返回交集新集合
symmetric_difference()返回对称差新集合
集合推导式按条件生成新集合

循环集合

集合(set)本质上是 无序、不重复的可迭代容器

  • 无序 → 遍历时顺序不固定。
  • 不重复 → 迭代时不会出现重复元素。
  • 可迭代 → 能直接用 forwhileenumerate()、推导式等方法进行循环。

for 循环遍历集合(最常用)

语法

for item in my_set:# 对 item 做操作

示例

my_set = {25, 12, 10, -21, 10, 100}   # 重复元素会自动去重
for item in my_set:print("Item:", item)

输出(顺序可能不同):

Item: 100
Item: 25
Item: 10
Item: -21
Item: 12

要点

  • 集合遍历时,不会保证固定顺序
  • 如果想要有序,可以 for item in sorted(my_set)

while 循环 + 迭代器遍历集合

集合是可迭代对象,可以用 iter() 转换成迭代器,再用 next() 手动获取。

示例

my_set = {1, 2, 3, 4, 5}
set_iterator = iter(my_set)while True:try:item = next(set_iterator)print("Item:", item)except StopIteration:break

输出:

Item: 1
Item: 2
Item: 3
Item: 4
Item: 5

适合场景:需要手动控制迭代过程,或者在 while 中加复杂逻辑。

使用 集合推导式

集合理解式 = for 循环 + 条件过滤 + 自动去重

语法

result = {表达式 for 变量 in 可迭代对象 if 条件}

示例

numbers = [1, 2, 3, 4, 5]
squares_of_evens = {x**2 for x in numbers if x % 2 == 0}
print(squares_of_evens)

输出:

{16, 4}

优点:一行生成集合,简洁高效。
注意:结果集合依旧无序。

使用 enumerate() 遍历集合

集合没有“索引”,但可以先转成 list,再用 enumerate() 获取索引和值。

示例

my_set = {1, 2, 3, 4, 5}
for index, item in enumerate(list(my_set)):print("Index:", index, "Item:", item)

输出:

Index: 0 Item: 1
Index: 1 Item: 2
Index: 3 Item: 3
Index: 4 Item: 4

要点:因为集合无序 → list(my_set) 的顺序也是随机的。

结合 add() 方法 + 循环

虽然 add() 不是循环工具,但常和 for 搭配用来“逐个添加元素到集合”。

示例

my_set = set()
for i in range(5):my_set.add(i)
print(my_set)

输出:

{0, 1, 2, 3, 4}

按条件遍历

my_set = {10, 25, 30, 45, 50}
for item in my_set:if item % 2 == 0:print("Even:", item)

同时遍历多个集合(zip)

set1 = {1, 2, 3}
set2 = {"a", "b", "c"}
for x, y in zip(set1, set2):print(x, y)

因为集合无序,结果配对不可预测。

保证有序遍历

my_set = {4, 2, 8, 1}
for item in sorted(my_set):print(item)

输出:

1
2
4
8

连接集合

在 Python 中,集合(set)的连接指的是:
两个或多个集合合并成一个新集合,同时自动去除重复元素。

特点:

  • 无重复:合并时会自动去重。
  • 无序:结果集合中的元素顺序不可预测。
  • 元素必须不可变:数字、字符串、元组可以;列表、字典不行。

使用 | 运算符(最简洁)

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s3 = s1 | s2
print(s3)

输出:

{1, 2, 3, 4, 5, 6, 7, 8}

| 就是数学上的并集运算。

使用 union() 方法

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s3 = s1.union(s2)
print(s3)

输出:

{1, 2, 3, 4, 5, 6, 7, 8}

| 作用相同,但语义更清晰,支持多个集合:

s3 = s1.union(s2, {9, 10})
print(s3)
# {1,2,3,4,5,6,7,8,9,10}

使用 update() 方法(就地修改)

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s1.update(s2)
print(s1)

输出:

{1, 2, 3, 4, 5, 6, 7, 8}

update() 会直接修改原集合,不返回新集合。

使用解包运算符 *

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s3 = {*s1, *s2}
print(s3)

输出:

{1, 2, 3, 4, 5, 6, 7, 8}

优点:直观、简洁,支持多个集合:

s3 = {*s1, *s2, *{9, 10}}

使用集合推导式(Set Comprehension)

set1 = {1, 2, 3}
set2 = {3, 4, 5}
joined_set = {x for s in [set1, set2] for x in s}
print(joined_set)

输出:

{1, 2, 3, 4, 5}

灵活性更强,可以加过滤条件:

joined_set = {x for s in [set1, set2] for x in s if x % 2 == 0}
print(joined_set)  # {2, 4}

使用迭代加法(for + add)

set1 = {1, 2, 3}
set2 = {3, 4, 5}joined_set = set()
for element in set1:joined_set.add(element)
for element in set2:joined_set.add(element)print(joined_set)

输出:

{1, 2, 3, 4, 5}

更“低层”的写法,适合需要一步步控制的场景。

保证有序合并

s1 = {3, 1, 2}
s2 = {5, 4}
result = sorted(s1 | s2)
print(result)   # [1, 2, 3, 4, 5]

批量合并多个集合

sets = [{1, 2}, {2, 3}, {3, 4}]
merged = set().union(*sets)
print(merged)   # {1, 2, 3, 4}

合并集合 + 条件过滤

s1 = {1, 2, 3}
s2 = {3, 4, 5}
merged = {x for x in (s1 | s2) if x > 2}
print(merged)   # {3, 4, 5}

复制集合

在 Python 中,复制集合就是:
创建一个 新集合,包含与原集合相同的元素,但 与原集合互不影响

和直接赋值不同:

a = {1, 2, 3}
b = a   # 只是引用
b.add(4)
print(a)  # {1, 2, 3, 4},原集合也被改了!

这里 b = a 并没有复制集合,只是让 ba 指向了同一个集合对象。

使用 copy() 方法(推荐)

lang1 = {"C", "C++", "Java", "Python"}
print("lang1:", lang1, "id(lang1):", id(lang1))lang2 = lang1.copy()
print("lang2:", lang2, "id(lang2):", id(lang2))lang1.add("PHP")
print("After updating lang1")
print("lang1:", lang1, "id(lang1):", id(lang1))
print("lang2:", lang2, "id(lang2):", id(lang2))

输出(id 不同,说明是两个独立集合):

lang1: {'Python', 'Java', 'C', 'C++'} id(lang1): 140711325235392
lang2: {'Python', 'Java', 'C', 'C++'} id(lang2): 140711325235648
After updating lang1
lang1: {'Python', 'C', 'C++', 'PHP', 'Java'} id(lang1): 140711325235392
lang2: {'Python', 'Java', 'C', 'C++'} id(lang2): 140711325235648

特点:

  • copy() 返回 浅拷贝
  • 如果集合里有可变对象(如列表),原集合和复制集合会共享它们。

使用 set() 构造函数

original_set = {1, 2, 3, 4}
copied_set = set(original_set)print("copied set:", copied_set)copied_set.add(5)
print("copied set:", copied_set)
print("original set:", original_set)

输出:

copied set: {1, 2, 3, 4}
copied set: {1, 2, 3, 4, 5}
original set: {1, 2, 3, 4}

特点:

  • set(iterable) 会遍历元素重新建一个集合。
  • 效果等同于 copy(),但语义上更偏向“从可迭代对象构建集合”。

使用 集合推导式(Set Comprehension)

original_set = {1, 2, 3, 4, 5}
copied_set = {x for x in original_set}
print("Copied set:", copied_set)

输出:

Copied set: {1, 2, 3, 4, 5}

特点:更灵活,可以添加条件:

copied_set = {x for x in original_set if x % 2 == 0}
print(copied_set)  # {2, 4}

复制多个集合合并

s1 = {1, 2}
s2 = {3, 4}
s3 = set(s1) | s2
print(s3)  # {1, 2, 3, 4}

深拷贝集合(当元素是可变对象时)

import copys1 = {1, 2, (3, 4), frozenset({5, 6})}
s2 = copy.deepcopy(s1)
print(s1 == s2)       # True
print(id(s1) == id(s2))  # False

快速生成副本并转换

s = {1, 2, 3}
list_copy = list(s)   # 转成列表
tuple_copy = tuple(s) # 转成元组

集合运算符

集合运算符的意义

Python 中的集合运算符是对数学集合论运算的实现。它们的作用是:

  • 组合多个集合(并集)
  • 找出共有元素(交集)
  • 找出差异(差集)
  • 找出独有部分(对称差)
  • 判断集合关系(子集、超集)

优点:写法简洁、效率高,很多场景比列表/字典更直观。

四大基础集合运算符

  1. 并集:|union()

    • 定义:包含两个集合中所有唯一元素。

    • 语法

      A | B
      A.union(B)
      
    • 图解:相当于数学的 A∪BA∪BAB

    • 示例

      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 | set2)             # {1, 2, 3, 4, 5}
      print(set1.union(set2))        # {1, 2, 3, 4, 5}
      
  2. 交集:&intersection()

    • 定义:包含两个集合中都存在的元素。

    • 语法

      A & B
      A.intersection(B)
      
    • 图解:相当于数学的 A∩BA∩BAB

    • 示例

      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 & set2)             # {3}
      print(set1.intersection(set2)) # {3}
      
  3. 差集:-difference()

    • 定义:集合 A 中有但 B 中没有的元素。

    • 语法

      A - B
      A.difference(B)
      
    • 注意:差集是 有方向的A - B != B - A

    • 图解:相当于数学的 A−BA−BAB

    • 示例

      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 - set2)             # {1, 2}
      print(set2 - set1)             # {4, 5}
      
  4. 对称差:^symmetric_difference()

    • 定义:属于 A 或 B,但不同时属于两者。

    • 语法

      A ^ B
      A.symmetric_difference(B)
      
    • 图解:相当于数学的 AΔBAΔBAΔB,等价于 (A - B) ∪ (B - A)

    • 示例

      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 ^ set2)                      # {1, 2, 4, 5}
      print(set1.symmetric_difference(set2))  # {1, 2, 4, 5}
      

子集、超集、相等关系运算

  1. 子集:<=issubset()

    • 定义:A 的所有元素都在 B 中。

    • 语法

      A <= B
      A.issubset(B)
      
    • 示例

      a = {1, 2}
      b = {1, 2, 3}
      print(a <= b)          # True
      print(a.issubset(b))   # True
      
  2. 真子集:<

    • 定义:A 是 B 的子集,但 A ≠ B。

    • 示例

      a = {1, 2}
      b = {1, 2, 3}
      print(a < b)   # True
      print(b < a)   # False
      
  3. 超集:>=issuperset()

    • 定义:A 包含 B 的所有元素。

    • 示例

      a = {1, 2, 3}
      b = {1, 2}
      print(a >= b)          # True
      print(a.issuperset(b)) # True
      
  4. 真超集:>

    • 定义:A 是 B 的超集,且 A ≠ B。

    • 示例

      a = {1, 2, 3}
      b = {1, 2}
      print(a > b)   # True
      
  5. 相等:==

    • 定义:A 和 B 含有相同元素(顺序不重要)。

    • 示例

      a = {1, 2, 3}
      b = {3, 2, 1}
      print(a == b)  # True
      

高级运算与技巧

  1. 多集合运算

    s1 = {1, 2, 3}
    s2 = {2, 3, 4}
    s3 = {3, 4, 5}
    print(s1 | s2 | s3)   # 并集:{1, 2, 3, 4, 5}
    print(s1 & s2 & s3)   # 交集:{3}
    
  2. 不相交测试:isdisjoint()

    a = {1, 2}
    b = {3, 4}
    print(a.isdisjoint(b))  # True(完全没有交集)
    
  3. 集合运算的“惰性”写法(链式)

    print(({1, 2, 3} | {2, 3, 4}) & {3, 4, 5})
    # {3, 4}
    

集合运算符一览表

运算符号方法说明
并集`AB`A.union(B)
交集A & BA.intersection(B)A ∩ B,共同元素
差集A - BA.difference(B)A 有而 B 没有
对称差A ^ BA.symmetric_difference(B)属于 A 或 B,但不同时属于
子集A <= BA.issubset(B)A 的元素全在 B 中
真子集A < B——A 是 B 的子集,但不相等
超集A >= BA.issuperset(B)A 包含 B 的所有元素
真超集A > B——A 是 B 的超集,但不相等
相等A == B——集合元素完全相同
不相交——A.isdisjoint(B)A 和 B 没有公共元素

集合方法

集合 (set):无序、元素唯一、可变(元素必须可哈希,例如数字、字符串、元组)。

用途:去重、成员测试、集合运算(并、交、差、对称差)。

两种集合类型

  • set —— 可变集合。
  • frozenset —— 不可变集合。

Python 提供了 三大类方法

  1. 添加和删除元素
  2. 集合运算(更新/返回新集合)
  3. 关系测试和工具方法

添加和删除元素方法

方法说明示例
add(elem)添加单个元素s.add(10)
clear()清空集合s.clear()
copy()返回集合的浅拷贝s2 = s.copy()
discard(elem)删除元素,如果不存在不会报错s.discard(99)
remove(elem)删除元素,不存在会报错 KeyErrors.remove(2)
pop()随机删除并返回一个元素x = s.pop()

代码示例:

s = {1, 2, 3}
s.add(4)             # {1, 2, 3, 4}
s.discard(10)        # 不报错
try:s.remove(10)     # KeyError
except KeyError:print("元素不存在!")
print(s.pop())       # 随机弹出一个元素
s.clear()            # 变成空集合 set()

注意:

  • discard vs remove:推荐用 discard,更安全。
  • pop() 是随机的,不要依赖返回顺序。

集合运算方法(返回新集合)

这些方法不会修改原集合,而是返回一个新集合。

方法说明示例
union(other)并集{1,2}.union({2,3}) → {1,2,3}
intersection(other)交集{1,2,3}.intersection({2,3,4}) → {2,3}
difference(other)差集{1,2,3}.difference({2}) → {1,3}
symmetric_difference(other)对称差{1,2,3}.symmetric_difference({3,4}) → {1,2,4}

代码示例:

a = {1, 2, 3}
b = {3, 4, 5}
print(a.union(b))              # {1, 2, 3, 4, 5}
print(a.intersection(b))       # {3}
print(a.difference(b))         # {1, 2}
print(a.symmetric_difference(b))  # {1, 2, 4, 5}

集合运算方法(原地更新)

这些方法会 修改原集合,相当于“就地操作”。

方法说明示例
update(other)并集更新(相当于 `=`)
intersection_update(other)交集更新(相当于 &=a.intersection_update(b)
difference_update(other)差集更新(相当于 -=a.difference_update(b)
symmetric_difference_update(other)对称差更新(相当于 ^=a.symmetric_difference_update(b)

代码示例:

a = {1, 2, 3}
b = {3, 4, 5}a.update(b)                   # a = {1, 2, 3, 4, 5}
a.intersection_update({2, 3}) # a = {2, 3}
a.difference_update({2})      # a = {3}
a.symmetric_difference_update({3, 10})  # a = {10}

注意:

  • update 系方法会 改变原集合,而不是返回新集合。
  • 如果不想破坏原集合,建议用 union() 等非更新方法。

关系与测试方法

方法说明示例
issubset(other)是否子集{1,2}.issubset({1,2,3}) → True
issuperset(other)是否超集{1,2,3}.issuperset({1,2}) → True
isdisjoint(other)是否无交集{1,2}.isdisjoint({3,4}) → True

代码示例:

a = {1, 2}
b = {1, 2, 3}
c = {4, 5}print(a.issubset(b))     # True
print(b.issuperset(a))   # True
print(a.isdisjoint(c))   # True

冻结集合

什么是冻结集合(frozenset)

  • 定义frozenset 是 Python 内置的不可变集合类型。
  • 特性
    1. 与普通集合 set 一样,元素唯一、无序。
    2. 不可变(immutable) —— 创建后不能修改,不能添加或删除元素。
    3. 因为不可变,frozenset 可以作为字典的键另一个集合的元素,而普通集合 set 不行。

这就是它和 set 最大的区别:set 可变,frozenset 不可变。

创建冻结集合

冻结集合通过内置函数 frozenset() 来创建。

# 从可迭代对象创建
f1 = frozenset([1, 2, 3, 4])
print(f1)   # frozenset({1, 2, 3, 4})# 从集合创建
s = {5, 6, 7}
f2 = frozenset(s)
print(f2)   # frozenset({5, 6, 7})# 空冻结集合
f3 = frozenset()
print(f3)   # frozenset()

冻结集合的不可变性

f = frozenset([1, 2, 3])# 不能添加
# f.add(4)      # AttributeError: 'frozenset' object has no attribute 'add'# 不能删除
# f.remove(2)   # AttributeError# 可以正常遍历
for i in f:print(i)# 可以用作字典键
d = {f: "hello"}
print(d)  # {frozenset({1, 2, 3}): 'hello'}

frozenset 支持的方法

虽然它不能修改自身,但支持 大多数集合运算,会返回新的 frozenset

方法描述示例
copy()返回自身(因为不可变,相当于原对象)f.copy()
union(other)并集,返回新 frozensetf1.union(f2)
intersection(other)交集f1.intersection(f2)
difference(other)差集f1.difference(f2)
symmetric_difference(other)对称差f1.symmetric_difference(f2)
issubset(other)是否是子集f1.issubset(f2)
issuperset(other)是否是超集f1.issuperset(f2)
isdisjoint(other)是否没有交集f1.isdisjoint(f2)

注意:像 add()remove()clear()update() 这些修改集合的方法 frozenset 不支持

frozenset 与 set 的区别总结

特性setfrozenset
可变性可变不可变
是否可哈希不能做字典键可以做字典键
是否能修改支持 add/remove/update不能修改
支持运算并、交、差、对称差并、交、差、对称差

frozenset 的典型应用场景

  1. 作为字典键

    graph = {frozenset([1, 2]): "edge between 1 and 2",frozenset([2, 3]): "edge between 2 and 3"
    }
    print(graph[frozenset([1, 2])])  # edge between 1 and 2
    
  2. 作为集合的元素

    s = {frozenset([1, 2]), frozenset([3, 4])}
    print(s)  # {frozenset({1, 2}), frozenset({3, 4})}
    
  3. 保持数据安全(不可变,防止意外修改)。

http://www.dtcms.com/a/391173.html

相关文章:

  • 【Leetcode hot 100】437.路径总和 Ⅲ
  • 神经网络学习笔记16——高效卷积神经网络架构汇总(SqueezeNet、MobileNet、ShuffleNet、EfficientNet、GhostNet)
  • 解码阳光电源技术壁垒:以IPD和数字化驱动模块化创新的研发体系
  • ARM体系结构—架构—指令集—寄存器—工作模式
  • 自适应全变分模型的图像平滑去噪与边缘保留算法
  • 主流前端框架比较
  • 前端接口参数序列化
  • 精细调光,稳定驱动:AP5165B 在低压LED照明中的卓越表现
  • EasyGBS如何实现企业园区视频监控一体化管理?
  • Ledit 16.3 版图软件全面系统性教程
  • Linux的DTS配置信息
  • 线程池全面解析:核心原理、参数配置与实践指南
  • 【Linux】自定义协议——网络计算器实现
  • Ubuntu 安装的docker-compose拉取镜像失败问题处理办法
  • 第35篇:AI前沿:具身智能(Embodied AI)与通用人工智能(AGI)
  • LangChain 入门到精通企业项目实践之 LangChain 聊天模型
  • crush情感分析项目01
  • 免费插件分享 | Missing References Search
  • ECU OTA测试
  • Jenkins运维之路(Slave容器节点)
  • Amazon Lambda + API Gateway 实战,无服务器架构入门
  • 芯片管脚的源电流与漏电流
  • Django+ARIMA微博舆情预警系统 SnowNLP情感分析 Echarts可视化 机器学习 大数据项目✅
  • SIMetrix 8.30仿真蓝牙天线上的无源滤波器
  • [x-cmd] 升级 x-cmd 指南
  • AXI4-Stream总线流控握手实战经验总结
  • RAWSim-O-main项目Trae解析
  • react固定容器标签超出n+展示
  • ​​HarmonyOS应用开发:从入门到实战的完整指南​
  • QT与GTK生态最新进展及特性对比(2025年)