文章目录
- 集合是Python中一种无序、可变的数据类型,用于存储唯一元素。它基于数学中的集合概念,支持并集、交集、差集等经典操作。 # 创建集合的多种方式 colors = {‘red’, ‘green’, ‘blue’, ‘red’} # 重复元素自动去重 print(colors) # 输出: {‘green’, ‘blue’, ‘red’} # 使用set()构造函数 numbers = set([1, 2, 3, 3, 2, 1]) print(numbers) # 输出: {1, 2, 3}
- 操作类型 方法 描述 时间复杂度 添加元素 add() 添加单个元素 O(1) 添加元素 update() 添加多个元素 O(k) 删除元素 remove() 删除指定元素(不存在则报错) O(1) 删除元素 discard() 删除指定元素(不存在不报错) O(1) 集合运算 union() 返回两个集合的并集 O(n+m) 集合运算 intersection() 返回两个集合的交集 O(min(n,m)) 集合运算 difference() 返回集合的差集 O(n) 集合运算 symmetric_difference() 返回对称差集 O(n+m)
- 案例一:数据清洗与去重 # 原始数据包含大量重复项 raw_data = [23, 45, 23, 67, 45, 89, 23, 45, 67, 23, 12] # 使用集合快速去重 unique_data = set(raw_data) print(f”原始数据量: {len(raw_data)}”) print(f”去重后数据量: {len(unique_data)}”) print(f”唯一值集合: {sorted(unique_data)}”) 案例二:用户兴趣标签系统 class UserInterestManager: def __init__(self): self.user_interests = {} def add_interest(self, user_id, interests): “””添加用户兴趣标签””” if user_id not in self.user_interests: self.user_interests[user_id] = set() self.user_interests[user_id].update(interests) def find_common_interests(self, user1_id, user2_id): “””查找两个用户的共同兴趣””” interests1 = self.user_interests.get(user1_id, set()) interests2 = self.user_interests.get(user2_id, set()) return interests1.intersection(interests2) def get_recommendations(self, user_id): “””基于其他用户兴趣推荐新标签””” user_interests = self.user_interests.get(user_id, set()) all_interests = set() for uid, interests in self.user_interests.items(): if uid != user_id: all_interests.update(interests) # 推荐用户还没有的兴趣标签 return all_interests – user_interests # 使用示例 manager = UserInterestManager() manager.add_interest(“user1”, {“python”, “AI”, “data science”}) manager.add_interest(“user2”, {“python”, “web development”, “AI”}) common = manager.find_common_interests(“user1”, “user2″) print(f”共同兴趣: {common}”) # 输出: {‘python’, ‘AI’}
- 如果说集合是流动的溪水,那么不可变集合就是凝固的水晶。frozenset具有集合的所有特性,但创建后无法修改,这使得它可以作为字典的键或其他集合的元素。 # 创建不可变集合 immutable_colors = frozenset([‘red’, ‘green’, ‘blue’, ‘red’]) print(immutable_colors) # 输出: frozenset({‘green’, ‘blue’, ‘red’}) # 尝试修改会引发错误 # immutable_colors.add(‘yellow’) # AttributeError: ‘frozenset’ object has no attribute ‘add’
- 特性 set frozenset 可变性 可变,可增删元素 不可变,创建后无法修改 哈希性 不可哈希,不能作为字典键 可哈希,可作为字典键 内存占用 动态变化 固定不变 线程安全 需要同步控制 天生线程安全 迭代速度 略快(因优化) 略慢 查找速度 O(1) O(1)
- 场景一:配置管理系统的常量定义 class SystemConfig: # 定义不可变的权限集合 READ_PERMISSIONS = frozenset([‘view’, ‘download’, ‘print’]) WRITE_PERMISSIONS = frozenset([‘create’, ‘edit’, ‘delete’, ‘upload’]) ADMIN_PERMISSIONS = frozenset([‘grant’, ‘revoke’, ‘audit’]) # 权限组映射 PERMISSION_GROUPS = { ‘reader’: READ_PERMISSIONS, ‘editor’: READ_PERMISSIONS | WRITE_PERMISSIONS, ‘administrator’: READ_PERMISSIONS | WRITE_PERMISSIONS | ADMIN_PERMISSIONS } @classmethod def check_permission(cls, user_group, required_permission): “””检查用户组是否拥有特定权限””” user_permissions = cls.PERMISSION_GROUPS.get(user_group, frozenset()) return required_permission in user_permissions # 使用示例 print(SystemConfig.check_permission(‘editor’, ‘edit’)) # True print(SystemConfig.check_permission(‘reader’, ‘delete’)) # False 场景二:图论中的顶点集合 class Graph: def __init__(self): # 使用frozenset作为字典键,表示边的关系 self.edges = {} def add_edge(self, vertex_set, weight): “””添加边,顶点集合作为键””” if len(vertex_set) != 2: raise ValueError(“边必须连接两个顶点”) frozen_vertices = frozenset(vertex_set) self.edges[frozen_vertices] = weight def get_edge_weight(self, vertex1, vertex2): “””获取边的权重””” key = frozenset([vertex1, vertex2]) return self.edges.get(key, None) def find_connected_vertices(self, vertex): “””查找与指定顶点相连的所有顶点””” connected = set() for edge in self.edges: if vertex in edge: connected.update(edge – {vertex}) return connected # 创建图结构 graph = Graph() graph.add_edge({‘A’, ‘B’}, 5) graph.add_edge({‘B’, ‘C’}, 3) graph.add_edge({‘A’, ‘C’}, 7) print(f”A-B权重: {graph.get_edge_weight(‘A’, ‘B’)}”) # 输出: 5 print(f”与B相连的顶点: {graph.find_connected_vertices(‘B’)}”) # 输出: {‘A’, ‘C’}
- # 传统方式 squares_set = set() for i in range(10): squares_set.add(i ** 2) # 使用集合推导式(更Pythonic) squares_set = {i ** 2 for i in range(10)} even_squares = {i ** 2 for i in range(10) if i % 2 == 0} print(f”所有平方数: {squares_set}”) print(f”偶数平方数: {even_squares}”)
- import time def find_common_elements_list(list1, list2): “””使用列表查找共同元素(低效)””” common = [] for item in list1: if item in list2 and item not in common: common.append(item) return common def find_common_elements_set(list1, list2): “””使用集合查找共同元素(高效)””” set1 = set(list1) set2 = set(list2) return list(set1.intersection(set2)) # 性能测试 large_list1 = list(range(10000)) large_list2 = list(range(5000, 15000)) start = time.time() result_list = find_common_elements_list(large_list1, large_list2) list_time = time.time() – start start = time.time() result_set = find_common_elements_set(large_list1, large_list2) set_time = time.time() – start print(f”列表方法耗时: {list_time:.4f}秒”) print(f”集合方法耗时: {set_time:.4f}秒”) print(f”性能提升: {list_time/set_time:.1f}倍”)
- class ProductRecommender: def __init__(self): # 用户购买历史:用户ID -> 购买商品ID集合 self.purchase_history = {} # 商品相似度:商品ID -> 相似商品ID集合 self.product_similarity = {} def record_purchase(self, user_id, product_ids): “””记录用户购买记录””” if user_id not in self.purchase_history: self.purchase_history[user_id] = set() self.purchase_history[user_id].update(product_ids) def calculate_similarity(self, product_id1, product_id2, common_buyers): “””计算商品相似度””” buyers1 = set() buyers2 = set() for user_id, products in self.purchase_history.items(): if product_id1 in products: buyers1.add(user_id) if product_id2 in products: buyers2.add(user_id) # 使用Jaccard相似度系数 intersection = len(buyers1.intersection(buyers2)) union = len(buyers1.union(buyers2)) if union == 0: return 0 similarity = intersection / union if similarity >= 0.1: # 相似度阈值 if product_id1 not in self.product_similarity: self.product_similarity[product_id1] = set() self.product_similarity[product_id1].add(product_id2) if product_id2 not in self.product_similarity: self.product_similarity[product_id2] = set() self.product_similarity[product_id2].add(product_id1) return similarity def recommend_products(self, user_id, max_recommendations=5): “””为用户推荐商品””” if user_id not in self.purchase_history: return [] purchased = self.purchase_history[user_id] recommendations = set() for product_id in purchased: similar = self.product_similarity.get(product_id, set()) # 排除已购买的商品 recommendations.update(similar – purchased) # 返回推荐列表(按某种规则排序) return list(recommendations)[:max_recommendations] # 模拟电商推荐系统 recommender = ProductRecommender() # 模拟购买记录 recommender.record_purchase(“user1”, {“p1”, “p2”, “p3”}) recommender.record_purchase(“user2”, {“p2”, “p3”, “p4”}) recommender.record_purchase(“user3”, {“p1”, “p3”, “p5”}) # 计算商品相似度 recommender.calculate_similarity(“p1”, “p2”, 2) recommender.calculate_similarity(“p2”, “p3”, 3) # 获取推荐 recs = recommender.recommend_products(“user1″) print(f”为用户1推荐的商品: {recs}”)
- 集合(set) 是可变、无序的唯一元素容器,适合动态数据去重和集合运算 不可变集合(frozenset) 是不可变的集合,可哈希,适合作为字典键或需要稳定性的场景 集合操作的时间复杂度通常为O(1),使其在处理大规模数据时极具优势 集合推导式提供了创建集合的简洁语法 在实际应用中,集合常用于数据清洗、关系建模、推荐系统等场景
- 在Python的世界里,set与frozenset不仅仅是一种数据结构,更是一种思维方式的体现。它们教会我们: 去繁就简:在信息爆炸的时代,去除冗余、保留本质是一种智慧 灵活与稳定:set的灵活性与frozenset的稳定性,如同人生的两种境界 关系思维:集合运算让我们以全新的视角看待数据之间的关系 正如数学家康托尔所言:"集合的本质在于其元素,而不在于元素的顺序或重复。"在编程的世界里,我们同样应该关注数据的本质,而非表象。 延伸阅读建议: Python官方文档中关于集合类型的详细说明 算法书籍中的哈希表原理(集合的底层实现) 离散数学中的集合论基础 数据库系统中的索引原理(与集合查找的相似性) 以上就是一文详解Python集合与不可变集合的详细内容,更多关于Python集合与不可变集合的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python可变集合和不可变集合的构造方法大全 Python列表、集合、字典核心区别举例详解 Python中字符串,列表,元组,集合及字典常见的遍历方式汇总 Python中集合推导式的实现
目录
- 引言:数据世界的独特之美
- 一、集合(set):动态的独特容器
- 1.1 集合的基本特性
- 1.2 集合的核心操作
- 1.3 集合的实用案例
- 二、不可变集合(frozenset):永恒的确定性
- 2.1 不可变集合的本质
- 2.2 性能对比分析
- 2.4 不可变集合的应用场景
- 三、高级技巧与最佳实践
- 3.1 集合推导式:优雅的数据转换
- 3.2 性能优化:集合运算的巧妙应用
- 3.3 实际项目中的应用:电商平台商品推荐
- 四、总结与思考
- 4.1 核心要点回顾
- 4.2 哲学思考
在Python的广阔天地中,数据结构如同繁星点点,各有其独特的光芒。今天,让我们一同走进集合(set) 与不可变集合(frozenset) 的奇妙世界——这两个看似简单却蕴含深意的数据结构,正是处理唯一性数据的优雅工具。
想象一下,你手中有一串珍珠项链,每颗珍珠都独一无二。集合就如同这条项链,它自动为你去除重复,只保留最纯粹的本质。而不可变集合,则是这条项链被永恒定格的那一刻,安全、稳定、不可更改。
集合是Python中一种无序、可变的数据类型,用于存储唯一元素。它基于数学中的集合概念,支持并集、交集、差集等经典操作。
# 创建集合的多种方式
colors = {'red', 'green', 'blue', 'red'} # 重复元素自动去重
print(colors) # 输出: {'green', 'blue', 'red'}
# 使用set()构造函数
numbers = set([1, 2, 3, 3, 2, 1])
print(numbers) # 输出: {1, 2, 3}
| 操作类型 | 方法 | 描述 | 时间复杂度 |
|---|---|---|---|
| 添加元素 | add() |
添加单个元素 | O(1) |
| 添加元素 | update() |
添加多个元素 | O(k) |
| 删除元素 | remove() |
删除指定元素(不存在则报错) | O(1) |
| 删除元素 | discard() |
删除指定元素(不存在不报错) | O(1) |
| 集合运算 | union() |
返回两个集合的并集 | O(n+m) |
| 集合运算 | intersection() |
返回两个集合的交集 | O(min(n,m)) |
| 集合运算 | difference() |
返回集合的差集 | O(n) |
| 集合运算 | symmetric_difference() |
返回对称差集 | O(n+m) |
案例一:数据清洗与去重
# 原始数据包含大量重复项
raw_data = [23, 45, 23, 67, 45, 89, 23, 45, 67, 23, 12]
# 使用集合快速去重
unique_data = set(raw_data)
print(f"原始数据量: {len(raw_data)}")
print(f"去重后数据量: {len(unique_data)}")
print(f"唯一值集合: {sorted(unique_data)}")
案例二:用户兴趣标签系统
class UserInterestManager:
def __init__(self):
self.user_interests = {}
def add_interest(self, user_id, interests):
"""添加用户兴趣标签"""
if user_id not in self.user_interests:
self.user_interests[user_id] = set()
self.user_interests[user_id].update(interests)
def find_common_interests(self, user1_id, user2_id):
"""查找两个用户的共同兴趣"""
interests1 = self.user_interests.get(user1_id, set())
interests2 = self.user_interests.get(user2_id, set())
return interests1.intersection(interests2)
def get_recommendations(self, user_id):
"""基于其他用户兴趣推荐新标签"""
user_interests = self.user_interests.get(user_id, set())
all_interests = set()
for uid, interests in self.user_interests.items():
if uid != user_id:
all_interests.update(interests)
# 推荐用户还没有的兴趣标签
return all_interests - user_interests
# 使用示例
manager = UserInterestManager()
manager.add_interest("user1", {"python", "AI", "data science"})
manager.add_interest("user2", {"python", "web development", "AI"})
common = manager.find_common_interests("user1", "user2")
print(f"共同兴趣: {common}") # 输出: {'python', 'AI'}
如果说集合是流动的溪水,那么不可变集合就是凝固的水晶。frozenset具有集合的所有特性,但创建后无法修改,这使得它可以作为字典的键或其他集合的元素。
# 创建不可变集合
immutable_colors = frozenset(['red', 'green', 'blue', 'red'])
print(immutable_colors) # 输出: frozenset({'green', 'blue', 'red'})
# 尝试修改会引发错误
# immutable_colors.add('yellow') # AttributeError: 'frozenset' object has no attribute 'add'
| 特性 | set | frozenset |
|---|---|---|
| 可变性 | 可变,可增删元素 | 不可变,创建后无法修改 |
| 哈希性 | 不可哈希,不能作为字典键 | 可哈希,可作为字典键 |
| 内存占用 | 动态变化 | 固定不变 |
| 线程安全 | 需要同步控制 | 天生线程安全 |
| 迭代速度 | 略快(因优化) | 略慢 |
| 查找速度 | O(1) | O(1) |
场景一:配置管理系统的常量定义
class SystemConfig:
# 定义不可变的权限集合
READ_PERMISSIONS = frozenset(['view', 'download', 'print'])
WRITE_PERMISSIONS = frozenset(['create', 'edit', 'delete', 'upload'])
ADMIN_PERMISSIONS = frozenset(['grant', 'revoke', 'audit'])
# 权限组映射
PERMISSION_GROUPS = {
'reader': READ_PERMISSIONS,
'editor': READ_PERMISSIONS | WRITE_PERMISSIONS,
'administrator': READ_PERMISSIONS | WRITE_PERMISSIONS | ADMIN_PERMISSIONS
}
@classmethod
def check_permission(cls, user_group, required_permission):
"""检查用户组是否拥有特定权限"""
user_permissions = cls.PERMISSION_GROUPS.get(user_group, frozenset())
return required_permission in user_permissions
# 使用示例
print(SystemConfig.check_permission('editor', 'edit')) # True
print(SystemConfig.check_permission('reader', 'delete')) # False
场景二:图论中的顶点集合
class Graph:
def __init__(self):
# 使用frozenset作为字典键,表示边的关系
self.edges = {}
def add_edge(self, vertex_set, weight):
"""添加边,顶点集合作为键"""
if len(vertex_set) != 2:
raise ValueError("边必须连接两个顶点")
frozen_vertices = frozenset(vertex_set)
self.edges[frozen_vertices] = weight
def get_edge_weight(self, vertex1, vertex2):
"""获取边的权重"""
key = frozenset([vertex1, vertex2])
return self.edges.get(key, None)
def find_connected_vertices(self, vertex):
"""查找与指定顶点相连的所有顶点"""
connected = set()
for edge in self.edges:
if vertex in edge:
connected.update(edge - {vertex})
return connected
# 创建图结构
graph = Graph()
graph.add_edge({'A', 'B'}, 5)
graph.add_edge({'B', 'C'}, 3)
graph.add_edge({'A', 'C'}, 7)
print(f"A-B权重: {graph.get_edge_weight('A', 'B')}") # 输出: 5
print(f"与B相连的顶点: {graph.find_connected_vertices('B')}") # 输出: {'A', 'C'}
# 传统方式
squares_set = set()
for i in range(10):
squares_set.add(i ** 2)
# 使用集合推导式(更Pythonic)
squares_set = {i ** 2 for i in range(10)}
even_squares = {i ** 2 for i in range(10) if i % 2 == 0}
print(f"所有平方数: {squares_set}")
print(f"偶数平方数: {even_squares}")
import time
def find_common_elements_list(list1, list2):
"""使用列表查找共同元素(低效)"""
common = []
for item in list1:
if item in list2 and item not in common:
common.append(item)
return common
def find_common_elements_set(list1, list2):
"""使用集合查找共同元素(高效)"""
set1 = set(list1)
set2 = set(list2)
return list(set1.intersection(set2))
# 性能测试
large_list1 = list(range(10000))
large_list2 = list(range(5000, 15000))
start = time.time()
result_list = find_common_elements_list(large_list1, large_list2)
list_time = time.time() - start
start = time.time()
result_set = find_common_elements_set(large_list1, large_list2)
set_time = time.time() - start
print(f"列表方法耗时: {list_time:.4f}秒")
print(f"集合方法耗时: {set_time:.4f}秒")
print(f"性能提升: {list_time/set_time:.1f}倍")
class ProductRecommender:
def __init__(self):
# 用户购买历史:用户ID -> 购买商品ID集合
self.purchase_history = {}
# 商品相似度:商品ID -> 相似商品ID集合
self.product_similarity = {}
def record_purchase(self, user_id, product_ids):
"""记录用户购买记录"""
if user_id not in self.purchase_history:
self.purchase_history[user_id] = set()
self.purchase_history[user_id].update(product_ids)
def calculate_similarity(self, product_id1, product_id2, common_buyers):
"""计算商品相似度"""
buyers1 = set()
buyers2 = set()
for user_id, products in self.purchase_history.items():
if product_id1 in products:
buyers1.add(user_id)
if product_id2 in products:
buyers2.add(user_id)
# 使用Jaccard相似度系数
intersection = len(buyers1.intersection(buyers2))
union = len(buyers1.union(buyers2))
if union == 0:
return 0
similarity = intersection / union
if similarity >= 0.1: # 相似度阈值
if product_id1 not in self.product_similarity:
self.product_similarity[product_id1] = set()
self.product_similarity[product_id1].add(product_id2)
if product_id2 not in self.product_similarity:
self.product_similarity[product_id2] = set()
self.product_similarity[product_id2].add(product_id1)
return similarity
def recommend_products(self, user_id, max_recommendations=5):
"""为用户推荐商品"""
if user_id not in self.purchase_history:
return []
purchased = self.purchase_history[user_id]
recommendations = set()
for product_id in purchased:
similar = self.product_similarity.get(product_id, set())
# 排除已购买的商品
recommendations.update(similar - purchased)
# 返回推荐列表(按某种规则排序)
return list(recommendations)[:max_recommendations]
# 模拟电商推荐系统
recommender = ProductRecommender()
# 模拟购买记录
recommender.record_purchase("user1", {"p1", "p2", "p3"})
recommender.record_purchase("user2", {"p2", "p3", "p4"})
recommender.record_purchase("user3", {"p1", "p3", "p5"})
# 计算商品相似度
recommender.calculate_similarity("p1", "p2", 2)
recommender.calculate_similarity("p2", "p3", 3)
# 获取推荐
recs = recommender.recommend_products("user1")
print(f"为用户1推荐的商品: {recs}")
- 集合(set) 是可变、无序的唯一元素容器,适合动态数据去重和集合运算
- 不可变集合(frozenset) 是不可变的集合,可哈希,适合作为字典键或需要稳定性的场景
- 集合操作的时间复杂度通常为O(1),使其在处理大规模数据时极具优势
- 集合推导式提供了创建集合的简洁语法
- 在实际应用中,集合常用于数据清洗、关系建模、推荐系统等场景
在Python的世界里,set与frozenset不仅仅是一种数据结构,更是一种思维方式的体现。它们教会我们:
- 去繁就简:在信息爆炸的时代,去除冗余、保留本质是一种智慧
- 灵活与稳定:
set的灵活性与frozenset的稳定性,如同人生的两种境界 - 关系思维:集合运算让我们以全新的视角看待数据之间的关系
正如数学家康托尔所言:"集合的本质在于其元素,而不在于元素的顺序或重复。"在编程的世界里,我们同样应该关注数据的本质,而非表象。
延伸阅读建议:
- Python官方文档中关于集合类型的详细说明
- 算法书籍中的哈希表原理(集合的底层实现)
- 离散数学中的集合论基础
- 数据库系统中的索引原理(与集合查找的相似性)
以上就是一文详解Python集合与不可变集合的详细内容,更多关于Python集合与不可变集合的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- Python可变集合和不可变集合的构造方法大全
- Python列表、集合、字典核心区别举例详解
- Python中字符串,列表,元组,集合及字典常见的遍历方式汇总
- Python中集合推导式的实现