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

Python快速入门专业版(三十九):Python集合:去重与集合运算(交集、并集、差集)

在这里插入图片描述

目录

  • 一、集合的定义与创建:无序且唯一的元素集合
    • 1. 基本创建方式
    • 2. 集合的元素限制:不可变类型
  • 二、集合的核心功能1:自动去重
    • 1. 列表去重的基本实现
    • 2. 保持去重后列表顺序(Python 3.7+)
    • 3. 实战案例:学生成绩去重
  • 三、集合的核心功能2:四大集合运算
    • 1. 交集(Intersection):两个集合的共同元素
      • 实现方式:
    • 2. 并集(Union):两个集合的所有元素(去重)
      • 实现方式:
    • 3. 差集(Difference):A有但B没有的元素
      • 实现方式:
    • 4. 对称差集(Symmetric Difference):仅一方有的元素
      • 实现方式:
    • 集合运算总结表
  • 四、集合的常用方法:添加、删除与判断
    • 1. 元素添加:`add()`与`update()`
    • 2. 元素删除:`remove()`、`discard()`与`pop()`
    • 3. 其他常用方法
  • 五、综合实战案例
    • 案例1:两个列表找共同元素(用交集实现)
    • 案例2:列表去重与排序(结合集合与列表方法)
    • 案例3:用户标签交集分析(集合运算实战)
  • 六、集合的使用场景与注意事项
    • 1. 适合使用集合的场景
    • 2. 注意事项
    • 3. 集合与其他数据结构的对比
  • 七、总结

集合(set)是Python中一种特殊的数据结构,它以无序、唯一的方式存储元素,类似于数学中的“集合”概念。集合的核心价值在于自动去重和高效的集合运算(如交集、并集、差集),在数据去重、关系判断(如共同元素、独有元素)等场景中应用广泛。

本文将系统讲解集合的定义、创建方式、核心特性,详细演示集合的去重功能、四大集合运算(交集、并集、差集、对称差集)及常用方法,并通过“列表去重”“查找共同元素”等实战案例,帮助你掌握集合的实用技巧。

一、集合的定义与创建:无序且唯一的元素集合

集合是由大括号{} 包裹的元素集合(元素间用逗号分隔),或通过set()函数创建。其核心特性为:

  • 无序性:元素的存储顺序与添加顺序无关,无法通过索引访问(区别于列表、元组)。
  • 唯一性:集合中不会出现重复元素,自动过滤重复值(最常用的特性之一)。
  • 元素类型限制:元素必须是不可变类型(如整数、字符串、元组),列表、字典等可变类型不能作为集合元素。

1. 基本创建方式

# 1. 用大括号创建集合(元素唯一,自动去重)
s1 = {1, 2, 3, 3, 4}  # 重复元素3被自动过滤
print(s1)  # 输出:{1, 2, 3, 4}(顺序可能不同,因集合无序)# 2. 创建空集合(必须用set(),不能用{},{}表示空字典)
empty_set = set()
print(type(empty_set))  # 输出:<class 'set'>
print(type({}))         # 输出:<class 'dict'>(空字典)# 3. 用set()函数创建(接收可迭代对象,如列表、字符串、元组)
# 列表转集合(自动去重)
list_to_set = set([1, 2, 2, 3])
print(list_to_set)  # 输出:{1, 2, 3}# 字符串转集合(按字符拆分,自动去重)
str_to_set = set("python")
print(str_to_set)  # 输出:{'p', 'y', 't', 'h', 'o', 'n'}(顺序随机)# 元组转集合
tuple_to_set = set((1, 2, 3, 3))
print(tuple_to_set)  # 输出:{1, 2, 3}

2. 集合的元素限制:不可变类型

集合的元素必须是不可变类型,若包含列表、字典等可变类型,会直接抛出TypeError

# 错误:列表是可变类型,不能作为集合元素
# invalid_set = {1, [2, 3]}  # 错误:TypeError: unhashable type: 'list'# 正确:元组是不可变类型,可作为集合元素
valid_set = {1, (2, 3), "hello"}
print(valid_set)  # 输出:{1, 'hello', (2, 3)}

二、集合的核心功能1:自动去重

集合的“唯一性”特性使其成为列表去重的最优工具之一。只需将列表转换为集合,再转回列表,即可快速去除重复元素(注意:转换后列表顺序会改变,因集合无序)。

1. 列表去重的基本实现

# 案例1:简单列表去重
original_list = [1, 2, 2, 3, 3, 3, 4]
# 步骤:列表→集合(去重)→列表(恢复列表类型)
unique_list = list(set(original_list))
print(unique_list)  # 输出:[1, 2, 3, 4](顺序可能不同)# 案例2:包含字符串的列表去重
str_list = ["apple", "banana", "apple", "orange", "banana"]
unique_str_list = list(set(str_list))
print(unique_str_list)  # 输出:['apple', 'banana', 'orange'](顺序随机)

2. 保持去重后列表顺序(Python 3.7+)

由于集合无序,直接转换会丢失原列表的顺序。若需保持顺序,可结合dict.fromkeys()(字典键唯一且Python 3.7+保留插入顺序)实现:

original_list = [2, 1, 3, 1, 2, 4]# 方法:利用字典键的唯一性和有序性
# 1. dict.fromkeys(original_list) 生成键为列表元素、值为None的字典(自动去重且保序)
# 2. .keys() 获取字典的键(即去重后的元素,顺序与原列表一致)
# 3. 转换为列表
unique_ordered_list = list(dict.fromkeys(original_list).keys())
print(unique_ordered_list)  # 输出:[2, 1, 3, 4](保持原顺序)

3. 实战案例:学生成绩去重

假设需要统计班级学生的独特分数(去除重复分数),用集合可快速实现:

# 班级学生成绩列表(含重复分数)
scores = [85, 90, 85, 95, 90, 80, 85, 95]# 去重并统计独特分数的数量
unique_scores = set(scores)
print(f"所有分数:{scores}")
print(f"独特分数:{unique_scores}")
print(f"独特分数数量:{len(unique_scores)}")  # 输出:独特分数数量:4

三、集合的核心功能2:四大集合运算

集合完全模拟了数学中的集合运算,支持交集、并集、差集、对称差集四种核心运算,每种运算都有运算符方法两种实现方式,运算效率极高(底层基于哈希表)。

假设有两个集合:

# 集合A:数学成绩≥90分的学生ID
A = {101, 102, 103, 104}
# 集合B:语文成绩≥90分的学生ID
B = {103, 104, 105, 106}

1. 交集(Intersection):两个集合的共同元素

定义:同时存在于集合A和集合B中的元素,对应数学中的“A∩BA \cap BAB”。
应用场景:查找两个群体的交集(如同时在数学和语文考试中得高分的学生)。

实现方式:

  • 运算符:A & B
  • 方法:A.intersection(B)(或B.intersection(A),结果相同)
# 计算交集:同时在A和B中的学生ID
common_students = A & B
# 或用方法:common_students = A.intersection(B)print(f"数学高分学生:{A}")
print(f"语文高分学生:{B}")
print(f"两科都高分的学生:{common_students}")  # 输出:{103, 104}

2. 并集(Union):两个集合的所有元素(去重)

定义:存在于集合A或集合B中的所有元素(自动去重),对应数学中的“A∪BA \cup BAB”。
应用场景:合并两个群体并去除重复(如统计数学或语文考试中得高分的所有学生)。

实现方式:

  • 运算符:A | B
  • 方法:A.union(B)(或B.union(A),结果相同)
# 计算并集:数学或语文高分的所有学生ID(去重)
all_excellent_students = A | B
# 或用方法:all_excellent_students = A.union(B)print(f"数学或语文高分的学生:{all_excellent_students}")  # 输出:{101, 102, 103, 104, 105, 106}
print(f"总人数:{len(all_excellent_students)}")  # 输出:总人数:6

3. 差集(Difference):A有但B没有的元素

定义:存在于集合A中,但不存在于集合B中的元素,对应数学中的“A−BA - BAB”。
应用场景:查找某个群体独有的元素(如数学高分但语文未得高分的学生)。

实现方式:

  • 运算符:A - B
  • 方法:A.difference(B)(注意:A-BB-A结果不同)
# 计算A-B:数学高分但语文未高分的学生
math_only_excellent = A - B
# 或用方法:math_only_excellent = A.difference(B)# 计算B-A:语文高分但数学未高分的学生
chinese_only_excellent = B - A
# 或用方法:chinese_only_excellent = B.difference(A)print(f"数学高分但语文未高分:{math_only_excellent}")  # 输出:{101, 102}
print(f"语文高分但数学未高分:{chinese_only_excellent}")  # 输出:{105, 106}

4. 对称差集(Symmetric Difference):仅一方有的元素

定义:存在于集合A或集合B中,但不同时存在于两个集合中的元素,对应数学中的“AΔBA \Delta BAΔB”(等价于“(A∪B)−(A∩B)(A \cup B) - (A \cap B)(AB)(AB)”)。
应用场景:查找两个群体的“独有元素合集”(如仅数学高分或仅语文高分的学生)。

实现方式:

  • 运算符:A ^ B
  • 方法:A.symmetric_difference(B)(或B.symmetric_difference(A),结果相同)
# 计算对称差集:仅数学高分或仅语文高分的学生
only_one_excellent = A ^ B
# 或用方法:only_one_excellent = A.symmetric_difference(B)print(f"仅一科高分的学生:{only_one_excellent}")  # 输出:{101, 102, 105, 106}
# 验证:对称差集 = 并集 - 交集
verify = (A | B) - (A & B)
print(f"验证结果(并集-交集):{verify}")  # 输出:{101, 102, 105, 106}

集合运算总结表

运算类型运算符方法含义案例结果(A={101,102,103,104}, B={103,104,105,106})
交集A & BA.intersection(B)A和B的共同元素{103, 104}
并集ABA或B的所有元素(去重){101,102,103,104,105,106}
差集(A-B)A - BA.difference(B)A有但B没有的元素{101, 102}
对称差集A ^ BA.symmetric_difference(B)仅一方有的元素{101,102,105,106}

四、集合的常用方法:添加、删除与判断

集合支持一系列实用方法,用于添加元素、删除元素、判断元素关系等,进一步扩展了集合的功能。

1. 元素添加:add()update()

  • s.add(x):向集合中添加单个元素(若元素已存在,不做任何操作)。
  • s.update(iterable):向集合中批量添加元素(接收可迭代对象,如列表、元组、集合,自动去重)。
s = {1, 2, 3}# 1. 添加单个元素
s.add(4)
print(s)  # 输出:{1, 2, 3, 4}
s.add(3)  # 添加已存在的元素,无变化
print(s)  # 输出:{1, 2, 3, 4}# 2. 批量添加元素(从列表添加)
s.update([4, 5, 6])  # 4已存在,自动去重
print(s)  # 输出:{1, 2, 3, 4, 5, 6}# 3. 批量添加元素(从集合添加)
s.update({6, 7, 8})
print(s)  # 输出:{1, 2, 3, 4, 5, 6, 7, 8}

2. 元素删除:remove()discard()pop()

  • s.remove(x):删除集合中的元素x,若x不存在,抛出KeyError
  • s.discard(x):删除集合中的元素x,若x不存在,不报错(推荐使用,更安全)。
  • s.pop():随机删除集合中的一个元素并返回该元素(因集合无序,无法指定删除位置)。
s = {1, 2, 3, 4, 5}# 1. remove():删除存在的元素
s.remove(3)
print(s)  # 输出:{1, 2, 4, 5}
# s.remove(6)  # 错误:KeyError: 6(元素不存在)# 2. discard():删除存在的元素
s.discard(4)
print(s)  # 输出:{1, 2, 5}
# 删除不存在的元素,无报错
s.discard(6)
print(s)  # 输出:{1, 2, 5}(无变化)# 3. pop():随机删除一个元素
deleted = s.pop()
print(f"删除的元素:{deleted}")  # 输出:删除的元素:1(随机,可能不同)
print(f"删除后集合:{s}")        # 输出:删除后集合:{2, 5}

3. 其他常用方法

  • s.clear():清空集合中的所有元素,使集合变为空集。
  • len(s):获取集合中元素的个数。
  • x in s:判断元素x是否在集合s中(返回布尔值)。
  • s.isdisjoint(t):判断两个集合是否“无交集”(无共同元素返回True,否则返回False)。
s = {1, 2, 3}
t = {4, 5, 6}# 清空集合
s.clear()
print(s)  # 输出:set()(空集)# 重新赋值
s = {1, 2, 3}# 获取元素个数
print(len(s))  # 输出:3# 判断元素是否存在
print(2 in s)  # 输出:True
print(4 in s)  # 输出:False# 判断两个集合是否无交集
print(s.isdisjoint(t))  # 输出:True(s和t无共同元素)
print(s.isdisjoint({3, 4}))  # 输出:False(s和{3,4}有共同元素3)

五、综合实战案例

案例1:两个列表找共同元素(用交集实现)

需求:给定两个列表,找出它们的共同元素(去重),要求高效实现。

def find_common_elements(list1, list2):"""找出两个列表的共同元素(去重)参数:list1: 第一个列表list2: 第二个列表返回:共同元素组成的列表(去重)"""# 步骤:列表→集合(去重)→交集(找共同元素)→列表(返回结果)set1 = set(list1)set2 = set(list2)common_set = set1 & set2  # 或 set1.intersection(set2)return list(common_set)# 测试
list_a = [1, 2, 3, 4, 5, 2, 3]
list_b = [3, 4, 5, 6, 7, 5, 6]
common = find_common_elements(list_a, list_b)
print(f"列表A:{list_a}print(f"列表A:{list_a}")
print(f"列表B:{list_b}")
print(f"共同元素(去重):{common}")  # 输出:共同元素(去重):[3, 4, 5](顺序可能不同)

解析

  • 先将两个列表转换为集合,利用集合的“唯一性”自动去重(如list_a中的重复元素23被过滤)。
  • 通过交集运算(set1 & set2)快速找到共同元素,效率远高于“双重循环遍历列表对比”(尤其在数据量大时)。
  • 最后将结果转换为列表,符合日常使用习惯。

案例2:列表去重与排序(结合集合与列表方法)

需求:对包含重复元素的列表去重,并按升序排序。

def deduplicate_and_sort(lst):"""列表去重并按升序排序参数:lst - 待处理的列表返回:去重且排序后的列表"""# 步骤:去重(列表→集合)→排序(集合→列表→sort())unique_set = set(lst)  # 去重unique_list = list(unique_set)  # 转换为列表unique_list.sort()  # 升序排序return unique_list# 测试
original = [5, 2, 8, 2, 3, 5, 1, 8]
result = deduplicate_and_sort(original)
print(f"原始列表:{original}")
print(f"去重排序后:{result}")  # 输出:去重排序后:[1, 2, 3, 5, 8]

优化:若需保持原列表的“首次出现顺序”并去重排序,可结合dict.fromkeys()

def deduplicate_preserve_order_and_sort(lst):# 保持首次出现顺序去重→排序ordered_unique = list(dict.fromkeys(lst).keys())  # 保序去重ordered_unique.sort()  # 排序return ordered_unique# 测试
original = [5, 2, 8, 2, 3, 5, 1, 8]
result = deduplicate_preserve_order_and_sort(original)
print(f"保序去重排序后:{result}")  # 输出:保序去重排序后:[1, 2, 3, 5, 8]

案例3:用户标签交集分析(集合运算实战)

需求:分析两个用户的兴趣标签,找出共同兴趣、独有兴趣,并统计兴趣重合度。

def analyze_user_tags(user1_tags, user2_tags):"""分析两个用户的标签交集、差集及重合度参数:user1_tags: 用户1的标签列表user2_tags: 用户2的标签列表"""# 转换为集合(去重)set1 = set(user1_tags)set2 = set(user2_tags)# 计算各类集合common_tags = set1 & set2  # 共同标签(交集)user1_only = set1 - set2   # 用户1独有标签(差集)user2_only = set2 - set1   # 用户2独有标签(差集)all_tags = set1 | set2     # 所有标签(并集)# 计算重合度(共同标签数 / 总标签数,保留2位小数)overlap_ratio = len(common_tags) / len(all_tags) if len(all_tags) > 0 else 0.0# 输出结果print("=" * 50)print("用户标签分析结果")print("=" * 50)print(f"用户1标签:{user1_tags}")print(f"用户2标签:{user2_tags}")print(f"\n共同兴趣标签:{common_tags}(共{len(common_tags)}个)")print(f"用户1独有标签:{user1_only}(共{len(user1_only)}个)")print(f"用户2独有标签:{user2_only}(共{len(user2_only)}个)")print(f"兴趣重合度:{overlap_ratio:.2f}{len(common_tags)}/{len(all_tags)})")print("=" * 50)# 测试数据
user1 = ["篮球", "音乐", "电影", "游戏", "音乐", "篮球"]  # 含重复标签
user2 = ["电影", "阅读", "音乐", "旅行", "阅读"]          # 含重复标签
analyze_user_tags(user1, user2)

输出结果

==================================================
用户标签分析结果
==================================================
用户1标签:['篮球', '音乐', '电影', '游戏', '音乐', '篮球']
用户2标签:['电影', '阅读', '音乐', '旅行', '阅读']共同兴趣标签:{'电影', '音乐'}(共2个)
用户1独有标签:{'篮球', '游戏'}(共2个)
用户2独有标签:{'阅读', '旅行'}(共2个)
兴趣重合度:0.33(2/6)
==================================================

解析

  • 先将用户标签列表转换为集合,自动去除重复标签(如用户1的重复“篮球”“音乐”)。
  • 通过交集、差集运算清晰区分“共同兴趣”“独有兴趣”,为用户画像、兴趣推荐提供数据支持。
  • 计算“兴趣重合度”(共同标签数/总标签数),量化两个用户的兴趣相似度。

六、集合的使用场景与注意事项

1. 适合使用集合的场景

  • 数据去重:快速去除列表、元组中的重复元素(核心场景)。
  • 关系判断:查找两个数据集的共同元素(交集)、独有元素(差集)、合并元素(并集)。
  • 成员检测:判断元素是否存在于集合中(x in set,效率高于x in list,尤其数据量大时)。
  • 无序唯一数据存储:存储无需保持顺序但需保证唯一性的数据(如用户ID、标签列表)。

2. 注意事项

  • 无序性:集合无法通过索引访问元素,若需按顺序操作,需先转换为列表(list(set))。
  • 元素类型限制:元素必须是不可变类型(整数、字符串、元组),列表、字典等可变类型不能作为集合元素。
  • 空集合创建:必须用set()创建空集合,{}表示空字典,而非空集合。
  • 集合运算的返回值:集合运算(如A & BA | B)返回新集合,不会修改原集合。

3. 集合与其他数据结构的对比

数据结构核心特性适用场景
集合(set)无序、唯一、支持集合运算去重、关系判断、成员检测
列表(list)有序、可重复、可修改存储有序动态数据(如待办事项)
元组(tuple)有序、可重复、不可修改存储固定结构数据(如坐标、配置)
字典(dict)键值对、无序(3.7+有序)存储关联数据(如用户信息、映射关系)

七、总结

集合是Python中极具特色的数据结构,其核心价值在于“自动去重”和“高效集合运算”,通过本文的学习,可总结出以下要点:

  1. 核心特性

    • 无序性:无法通过索引访问,元素存储顺序与添加顺序无关。
    • 唯一性:自动过滤重复元素,适合去重场景。
    • 不可变元素:元素必须是不可变类型(如整数、字符串、元组)。
  2. 核心功能

    • 去重:通过list(set(lst))快速去除列表重复元素。
    • 集合运算:交集(&)、并集(|)、差集(-)、对称差集(^),高效处理数据关系。
    • 常用方法add()(添加元素)、discard()(安全删除)、clear()(清空)等。
  3. 实战技巧

    • 大数量数据去重优先用集合,效率远高于列表双重循环。
    • 查找共同元素、独有元素时,直接使用集合交集、差集运算,代码简洁高效。
    • 需保持原顺序去重时,结合dict.fromkeys()实现(Python 3.7+)。

掌握集合的使用,能让你在数据去重、关系分析等场景中写出更简洁、高效的代码,是Python数据处理的重要工具之一。

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

相关文章:

  • pytorch 中meshgrid()函数详解
  • 深度探秘GAIA:一个为下一代AI量身打造的挑战性基准
  • 今日分享C++ ---继承
  • TableGPT:浙江大学发布的表格大模型
  • Linux 概述
  • 领码学堂·定时任务新思维[二]——七大替代方案总览:场景、优缺点与快速选型
  • NLP:详解FastText
  • 【力扣】hot100系列(一)哈希部分解析(多解法+时间复杂度分析)
  • 用AI开发HTML双语阅读工具助力英语阅读
  • AI论文速读 | 当大语言模型遇上时间序列:大语言模型能否执行多步时间序列推理与推断
  • 如何使用升腾C92主机搭建本地Linux编译服务器并通过Windows映射访问共享目录
  • 测试DuckDB-rs项目中的示例程序
  • 分布式协议与算法实战-实战篇
  • 【硬件-笔试面试题-105】硬件/电子工程师,笔试面试题(知识点:详细讲讲什么是链表和数组)
  • 【获取地址栏的搜索关键字】功能-总结
  • 关于__sync_bool_compare_and_swap的使用及在多核多线程下使用时的思考
  • 【嵌入式简单外设篇】-433MHz 无线遥控模块
  • 计算机视觉(opencv)实战三十——摄像头实时风格迁移,附多种风格转换
  • 【数据分享】《中国农村统计年鉴》(1985-2024年)全pdf和excel
  • 2025年中国研究生数学建模竞赛“华为杯”C题 围岩裂隙精准识别与三维模型重构完整高质量成品 思路 代码 结果分享!全网首发!
  • [Linux]文件与 fd
  • FFmpeg 深入精讲(二)FFmpeg 初级开发
  • 睡眠脑电技术文章大纲
  • 计算机等级考试Python语言程序设计备考•第二练
  • 【Python】面向对象(一)
  • Jetson 设备监控利器:Jtop 使用方式(安装、性能模式、常用页面)
  • 「数据获取」《商洛统计年鉴》(2001-2024)
  • 链表的探索研究
  • 2025年工程项目管理软件全面测评
  • JAVA算法练习题day17