Python Set 集合完全指南:使用与遍历详解

1. 什么是 Set 集合?

在 Python 中,Set(集合)是一种无序、不重复元素的数据结构。它基于数学中的集合概念,主要用于成员关系测试和消除重复元素。

Set 的主要特点:

  • 无序性:元素没有固定顺序
  • 唯一性:自动去除重复元素
  • 可变性:可以添加或删除元素(frozenset 除外)
  • 可哈希性:元素必须是不可变类型

2. Set 的创建方法

2.1 使用花括号创建

# 创建包含元素的集合
fruits = {'apple', 'banana', 'orange', 'apple'}
print(fruits)  # 输出: {'banana', 'orange', 'apple'}(重复的 'apple' 被自动去除)

2.2 使用 set() 函数创建

# 从列表创建集合
numbers = set([1, 2, 3, 2, 4, 1])
print(numbers)  # 输出: {1, 2, 3, 4}

# 从字符串创建集合(每个字符作为元素)
chars = set('hello')
print(chars)  # 输出: {'h', 'e', 'l', 'o'}

# 创建空集合(必须使用 set(),不能用 {})
empty_set = set()
print(type(empty_set))  # 输出: <class 'set'>

2.3 使用集合推导式

# 创建 1-10 的平方集合
squares = {x**2 for x in range(1, 11)}
print(squares)  # 输出: {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

# 创建只包含偶数的平方集合
even_squares = {x**2 for x in range(1, 11) if x % 2 == 0}
print(even_squares)  # 输出: {16, 4, 36, 100, 64}

3. Set 的基本操作

3.1 添加元素

my_set = {1, 2, 3}

# 添加单个元素
my_set.add(4)
print(my_set)  # 输出: {1, 2, 3, 4}

# 添加多个元素
my_set.update([5, 6, 7])
print(my_set)  # 输出: {1, 2, 3, 4, 5, 6, 7}

# 添加已存在的元素(不会有任何效果)
my_set.add(3)
print(my_set)  # 输出: {1, 2, 3, 4, 5, 6, 7}

3.2 删除元素

my_set = {1, 2, 3, 4, 5}

# remove() - 删除指定元素,元素不存在会报错
my_set.remove(3)
print(my_set)  # 输出: {1, 2, 4, 5}

# discard() - 删除指定元素,元素不存在不会报错
my_set.discard(2)
my_set.discard(10)  # 不会报错
print(my_set)  # 输出: {1, 4, 5}

# pop() - 随机删除并返回一个元素
removed = my_set.pop()
print(f"删除了: {removed}, 剩余: {my_set}")

# clear() - 清空集合
my_set.clear()
print(my_set)  # 输出: set()

3.3 集合运算

A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# 并集
union_set = A | B  # 或 A.union(B)
print(f"并集: {union_set}")  # 输出: {1, 2, 3, 4, 5, 6, 7, 8}

# 交集
intersection_set = A & B  # 或 A.intersection(B)
print(f"交集: {intersection_set}")  # 输出: {4, 5}

# 差集
difference_set = A - B  # 或 A.difference(B)
print(f"A-B差集: {difference_set}")  # 输出: {1, 2, 3}

# 对称差集(只属于一个集合的元素)
symmetric_diff = A ^ B  # 或 A.symmetric_difference(B)
print(f"对称差集: {symmetric_diff}")  # 输出: {1, 2, 3, 6, 7, 8}

4. Set 的遍历方法

4.1 使用 for 循环直接遍历

colors = {'red', 'green', 'blue', 'yellow'}

print("直接遍历集合:")
for color in colors:
    print(f"- {color}")

# 输出示例(顺序可能不同):
# - red
# - green
# - blue
# - yellow

4.2 使用 enumerate() 获取索引

fruits = {'apple', 'banana', 'orange', 'grape'}

print("带索引的遍历:")
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

# 输出示例(索引从0开始,但顺序不确定):
# 0: banana
# 1: orange
# 2: apple
# 3: grape

4.3 转换为列表后遍历

numbers = {10, 20, 30, 40, 50}

# 转换为列表(会丢失集合特性,但可以控制顺序)
sorted_numbers = sorted(numbers)  # 按升序排序
print("按升序遍历:")
for num in sorted_numbers:
    print(num)

# 输出:
# 10
# 20
# 30
# 40
# 50

4.4 遍历时修改集合(使用副本)

original_set = {1, 2, 3, 4, 5}

# 错误做法:遍历时直接修改原集合
# for num in original_set:
#     if num % 2 == 0:
#         original_set.remove(num)  # 可能引发 RuntimeError

# 正确做法:遍历副本,修改原集合
print("删除偶数元素:")
for num in original_set.copy():  # 使用副本遍历
    if num % 2 == 0:
        original_set.remove(num)
        print(f"删除了 {num}")

print(f"最终集合: {original_set}")  # 输出: {1, 3, 5}

4.5 使用 while 循环遍历

my_set = {'a', 'b', 'c', 'd'}
set_copy = my_set.copy()  # 创建副本用于遍历

print("使用 while 循环遍历:")
while set_copy:
    element = set_copy.pop()  # 随机弹出元素
    print(f"当前元素: {element}")
    # 可以对原集合进行操作
    if element == 'b':
        my_set.add('new_element')

print(f"原集合最终状态: {my_set}")

5. 高级遍历技巧

5.1 条件遍历

data_set = {15, 22, 8, 31, 45, 12, 7}

print("大于20的元素:")
for num in data_set:
    if num > 20:
        print(num)

print("\n能被3整除的元素:")
divisible_by_3 = {x for x in data_set if x % 3 == 0}
for num in divisible_by_3:
    print(num)

5.2 嵌套集合遍历

# 集合的集合(需要将内层集合转换为 frozenset)
set_of_sets = {
    frozenset({1, 2, 3}),
    frozenset({4, 5, 6}),
    frozenset({7, 8, 9})
}

print("遍历嵌套集合:")
for inner_set in set_of_sets:
    print(f"子集: {set(inner_set)}")
    for element in inner_set:
        print(f"  - {element}")

5.3 遍历集合并执行操作

# 示例:统计字符频率
text = "python programming is fun with python"
words = text.split()
unique_words = set(words)

print("单词统计:")
for word in unique_words:
    count = words.count(word)
    print(f"'{word}': 出现 {count} 次")

# 示例:查找共同兴趣
alice_interests = {'reading', 'coding', 'hiking', 'music'}
bob_interests = {'coding', 'music', 'gaming', 'cooking'}

print("\n共同兴趣:")
common_interests = alice_interests & bob_interests
for interest in common_interests:
    print(f"- {interest}")

6. 性能考虑与最佳实践

6.1 成员测试性能

import time

# 创建大数据集
large_list = list(range(1000000))
large_set = set(large_list)

# 测试列表查找性能
target = 999999
start = time.time()
found_in_list = target in large_list
list_time = time.time() - start

# 测试集合查找性能
start = time.time()
found_in_set = target in large_set
set_time = time.time() - start

print(f"列表查找时间: {list_time:.6f} 秒")
print(f"集合查找时间: {set_time:.6f} 秒")
print(f"集合比列表快 {list_time/set_time:.1f} 倍")

6.2 遍历性能对比

import time

# 准备测试数据
test_data = set(range(1000000))

# 方法1:直接遍历
start = time.time()
total1 = 0
for num in test_data:
    total1 += num
time1 = time.time() - start

# 方法2:转换为列表后遍历
start = time.time()
total2 = 0
for num in list(test_data):
    total2 += num
time2 = time.time() - start

print(f"直接遍历时间: {time1:.4f} 秒")
print(f"转列表后遍历时间: {time2:.4f} 秒")
print(f"直接遍历比转列表快 {time2/time1:.2f} 倍")

6.3 最佳实践总结

  1. 去重优先使用集合:快速去除列表中的重复元素
  2. 成员测试用集合:O(1)时间复杂度 vs 列表的 O(n)
  3. 遍历时不要修改原集合:使用副本或推导式
  4. 需要顺序时先排序:使用 sorted() 获取有序列表
  5. 大数据集考虑性能:集合操作通常比列表更快

7. 实际应用示例

7.1 数据清洗

# 去除重复记录
raw_data = [
    {'id': 1, 'name': 'Alice'},
    {'id': 2, 'name': 'Bob'},
    {'id': 1, 'name': 'Alice'},  # 重复记录
    {'id': 3, 'name': 'Charlie'},
    {'id': 2, 'name': 'Bob'},    # 重复记录
]

# 使用集合记录已处理的ID
processed_ids = set()
clean_data = []

for record in raw_data:
    if record['id'] not in processed_ids:
        processed_ids.add(record['id'])
        clean_data.append(record)

print(f"原始数据: {len(raw_data)} 条")
print(f"清洗后数据: {len(clean_data)} 条")

7.2 标签系统

class TagSystem:
    def __init__(self):
        self.tags = set()
    
    def add_tags(self, *new_tags):
        """添加多个标签"""
        self.tags.update(new_tags)
        print(f"添加标签: {new_tags}")
    
    def remove_tag(self, tag):
        """移除标签"""
        if tag in self.tags:
            self.tags.remove(tag)
            print(f"移除标签: {tag}")
        else:
            print(f"标签不存在: {tag}")
    
    def find_common_tags(self, other_system):
        """查找共同标签"""
        return self.tags & other_system.tags
    
    def display_tags(self):
        """显示所有标签"""
        print("当前标签:")
        for i, tag in enumerate(sorted(self.tags), 1):
            print(f"{i}. {tag}")

# 使用示例
system1 = TagSystem()
system1.add_tags('python', 'programming', 'tutorial')
system1.add_tags('python', 'advanced')  # 重复的 'python' 不会被添加

system2 = TagSystem()
system2.add_tags('python', 'beginner', 'tutorial')

print("\n系统1标签:")
system1.display_tags()

print("\n系统2标签:")
system2.display_tags()

print("\n共同标签:")
common = system1.find_common_tags(system2)
for tag in common:
    print(f"- {tag}")

7.3 权限管理系统

class PermissionManager:
    def __init__(self):
        self.user_permissions = {}
    
    def grant_permissions(self, user, *permissions):
        """授予用户权限"""
        if user not in self.user_permissions:
            self.user_permissions[user] = set()
        self.user_permissions[user].update(permissions)
    
    def revoke_permissions(self, user, *permissions):
        """撤销用户权限"""
        if user in self.user_permissions:
            self.user_permissions[user].difference_update(permissions)
    
    def check_permission(self, user, permission):
        """检查用户是否有特定权限"""
        return user in self.user_permissions and permission in self.user_permissions[user]
    
    def list_user_permissions(self, user):
        """列出用户所有权限"""
        if user in self.user_permissions:
            print(f"{user} 的权限:")
            for perm in sorted(self.user_permissions[user]):
                print(f"  - {perm}")
        else:
            print(f"用户 {user} 没有权限")

# 使用示例
manager = PermissionManager()

# 授予权限
manager.grant_permissions('alice', 'read', 'write', 'delete')
manager.grant_permissions('bob', 'read', 'execute')

# 检查权限
print(f"Alice 有 write 权限: {manager.check_permission('alice', 'write')}")
print(f"Bob 有 delete 权限: {manager.check_permission('bob', 'delete')}")

# 列出权限
manager.list_user_permissions('alice')
manager.list_user_permissions('bob')

# 撤销权限
manager.revoke_permissions('alice', 'delete')
print(f"\n撤销后 Alice 有 delete 权限: {manager.check_permission('alice', 'delete')}")

8. 总结

Python 的 Set 集合是一个强大而高效的数据结构,特别适合处理需要唯一性和快速成员测试的场景。通过本文的学习,你应该已经掌握了:

  1. Set 的创建:使用花括号、set()函数和集合推导式
  2. 基本操作:添加、删除、集合运算等
  3. 多种遍历方法:for循环、enumerate、排序遍历等
  4. 高级技巧:条件遍历、嵌套遍历、性能优化
  5. 实际应用:数据清洗、标签系统、权限管理等

记住集合的核心优势:去重、快速查找、集合运算。在实际编程中,合理使用集合可以显著提高代码的效率和可读性。

最后提示:虽然集合是无序的,但从 Python 3.7 开始,字典和集合的插入顺序会被保留(作为实现细节),但不应依赖这一特性编写代码。如果需要有序集合,请使用 collections.OrderedDict 或排序后的列表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值