集合是Python中一種非常有用的數據結構,它與列表類似但具有獨特的特性。本文將全面介紹集合的所有知識點,從基礎概念到高級用法,幫助初學者徹底掌握集合的使用。
1. 集合簡介
1.1 什么是集合?
集合(Set)是Python中的一種無序、不重復元素的容器。它類似于數學中的集合概念,具有以下主要特點:
元素唯一性:集合中的元素不會重復
無序性:元素沒有固定順序
可變性:可以添加或刪除元素
元素不可變性:集合中的元素必須是不可變類型(如數字、字符串、元組等)
1.2 為什么需要集合?
集合主要解決兩個問題:
去重:自動去除重復元素
關系運算:高效執行集合運算(交集、并集、差集等)
2. 集合的創建與基本操作
2.1 創建集合
# 方法1:使用花括號(注意與字典的區別)
s1 = {1, 2, 3, 2, 1} # 自動去重,結果為{1, 2, 3}# 方法2:使用set()構造函數
s2 = set() # 創建空集合
s3 = set([1, 2, 3, 2, 1]) # 從列表創建,結果為{1, 2, 3}# 方法3:從字符串創建(會拆分為字符)
s4 = set("hello") # 結果為{'h', 'e', 'l', 'o'}
注意:創建空集合必須使用set()
,因為{}
表示空字典。
2.2 集合的元素特性
集合中的元素必須滿足:
不可變:不能是列表、字典、集合等可變類型
可哈希:必須實現
__hash__
方法
合法元素示例:
valid_set = {1, "hello", (1, 2, 3), True, 3.14}
非法元素示例:
invalid_set = {[1, 2], {"a": 1}, {1, 2}} # 會報TypeError
2.3 集合的去重特性
集合自動去除重復元素:
numbers = [1, 2, 3, 2, 1, 4, 5, 4]
unique_numbers = set(numbers) # 結果為{1, 2, 3, 4, 5}
3. 集合的基本操作
3.1 添加元素
s = {1, 2, 3}# 添加單個元素
s.add(4) # s變為{1, 2, 3, 4}# 添加多個元素
s.update([5, 6, 7]) # s變為{1, 2, 3, 4, 5, 6, 7}
s.update({8, 9}, [10, 11]) # 可以混合添加
3.2 刪除元素
s = {1, 2, 3, 4, 5, 6}# 方法1:remove() - 刪除指定元素,不存在則報錯
s.remove(3) # s變為{1, 2, 4, 5, 6}# 方法2:discard() - 刪除指定元素,不存在不報錯
s.discard(10) # 無變化# 方法3:pop() - 隨機刪除并返回一個元素
item = s.pop() # 隨機刪除一個元素# 方法4:clear() - 清空集合
s.clear() # s變為set()
3.3 查詢操作
s = {1, 2, 3, 4, 5}# 檢查元素是否存在
print(3 in s) # 輸出: True
print(6 not in s) # 輸出: True# 獲取集合長度
print(len(s)) # 輸出: 5
3.4 集合的不可修改性
集合中的元素不能直接修改,因為集合是基于哈希表實現的。如果需要"修改"元素,只能先刪除再添加:
s = {1, 2, 3}# 錯誤做法(會報錯)
# s[0] = 10 # 正確做法:先刪除再添加
s.remove(1)
s.add(10) # s變為{2, 3, 10}
4. 集合的關系運算
集合最強大的功能之一是能夠執行數學上的集合運算。
4.1 交集(Intersection)
返回兩個集合中都存在的元素。
s1 = {1, 2, 3}
s2 = {2, 3, 4}# 方法1:使用&運算符
print(s1 & s2) # 輸出: {2, 3}# 方法2:使用intersection()方法
print(s1.intersection(s2)) # 輸出: {2, 3}
4.2 并集(Union)
返回兩個集合中所有不重復的元素。
# 方法1:使用|運算符
print(s1 | s2) # 輸出: {1, 2, 3, 4}# 方法2:使用union()方法
print(s1.union(s2)) # 輸出: {1, 2, 3, 4}
4.3 差集(Difference)
返回只存在于第一個集合中的元素。
# 方法1:使用-運算符
print(s1 - s2) # 輸出: {1}
print(s2 - s1) # 輸出: {4}# 方法2:使用difference()方法
print(s1.difference(s2)) # 輸出: {1}
4.4 對稱差集(Symmetric Difference)
返回兩個集合中不相同的元素(即只存在于其中一個集合中的元素)。
# 方法1:使用^運算符
print(s1 ^ s2) # 輸出: {1, 4}# 方法2:使用symmetric_difference()方法
print(s1.symmetric_difference(s2)) # 輸出: {1, 4}
4.5 子集與超集
判斷一個集合是否完全包含于或包含另一個集合。
a = {1, 2, 3}
b = {1, 2}# 子集判斷
print(b < a) # 輸出: True(b是a的真子集)
print(b <= a) # 輸出: True(b是a的子集或相等)# 超集判斷
print(a > b) # 輸出: True(a是b的真超集)
print(a >= b) # 輸出: True(a是b的超集或相等)# 方法形式
print(b.issubset(a)) # 輸出: True
print(a.issuperset(b)) # 輸出: True
4.6 集合相等性
判斷兩個集合是否包含相同的元素(不考慮順序)。
x = {1, 2, 3}
y = {3, 2, 1}print(x == y) # 輸出: True
print(x != y) # 輸出: False
5. 集合的高級用法
5.1 集合推導式
類似于列表推導式,可以快速生成集合。
# 基本語法
{expression for item in iterable}
{expression for item in iterable if condition}# 示例1:創建平方數集合
squares = {x**2 for x in range(10)}
# 輸出: {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}# 示例2:篩選偶數平方
even_squares = {x**2 for x in range(10) if x % 2 == 0}
# 輸出: {0, 4, 16, 36, 64}# 示例3:字符串處理
words = ["hello", "world", "python"]
unique_chars = {char for word in words for char in word}
# 輸出: {'d', 'e', 'h', 'l', 'n', 'o', 'p', 'r', 't', 'w', 'y'}
5.2 凍結集合(frozenset)
frozenset
是不可變集合,可以作為字典的鍵或另一個集合的元素。
fs = frozenset([1, 2, 3, 2, 1]) # 創建凍結集合# 可以作為字典的鍵
d = {fs: "frozen set"} # 合法# 可以作為集合的元素
s = {fs, frozenset([4, 5, 6])} # 合法
5.3 集合與列表的轉換
# 列表去重(常用技巧)
lst = [1, 2, 3, 2, 1, 4, 5, 4]
unique_lst = list(set(lst)) # 轉換為集合去重,再轉回列表# 注意:順序可能改變
print(unique_lst) # 可能輸出: [1, 2, 3, 4, 5]
5.4 集合的性能優勢
集合基于哈希表實現,查找操作時間復雜度為O(1),遠快于列表的O(n)。
# 查找元素性能比較
big_list = list(range(1000000))
big_set = set(big_list)# 列表查找(慢)
%timeit 999999 in big_list # 約10ms# 集合查找(快)
%timeit 999999 in big_set # 約100ns
6. 集合的實際應用場景
6.1 數據去重
# 去除重復單詞
text = "hello world hello python world"
words = text.split()
unique_words = set(words) # {'hello', 'world', 'python'}
6.2 關系測試
# 找出共同好友
alice_friends = {"Bob", "Charlie", "Diana"}
bob_friends = {"Alice", "Charlie", "Eve"}common_friends = alice_friends & bob_friends # {'Charlie'}
6.3 成員快速查找
# 高效檢查元素是否存在
valid_users = {"alice", "bob", "charlie"}
username = input("請輸入用戶名: ")
if username in valid_users:print("歡迎回來!")
else:print("用戶名不存在")
6.4 過濾數據
# 篩選出只出現一次的元素
from collections import Counterdata = [1, 2, 3, 2, 1, 4, 5, 4, 6]
counts = Counter(data)
unique_elements = {x for x in data if counts[x] == 1} # {3, 5, 6}
7. 集合與其他數據結構的比較
特性 | 集合(set) | 列表(list) | 字典(dict) |
---|---|---|---|
有序性 | 無序 | 有序 | Python 3.7+有序 |
元素唯一性 | 唯一 | 可重復 | 鍵唯一 |
可變性 | 可變 | 可變 | 可變 |
元素類型 | 必須不可變 | 任意 | 鍵必須不可變,值任意 |
查找速度 | O(1) | O(n) | O(1) |
主要用途 | 去重、關系運算 | 有序數據存儲 | 鍵值對映射 |
8. 常見問題與解答
Q1: 為什么集合是無序的?
集合基于哈希表實現,為了快速查找(O(1)時間復雜度),元素存儲位置由哈希值決定,因此不保持插入順序。
注意:Python 3.7+中,集合實際上保持了插入順序,但這被視為實現細節,不應依賴。
Q2: 集合和字典有什么關系?
集合相當于只有鍵沒有值的字典。實際上,Python的集合就是使用字典實現的,只是所有值都是None
。
Q3: 如何選擇使用列表還是集合?
需要保持順序或允許重復 → 使用列表
需要快速查找或去重 → 使用集合
需要關系運算 → 使用集合
Q4: 為什么集合的元素必須是不可變的?
因為集合基于哈希表實現,可變對象無法生成固定哈希值,會導致集合內部結構混亂。
9. 練習題
練習1:去重統計
# 統計一段文本中不同單詞的數量
text = """Python is an easy to learn powerful programming language.
It has efficient high-level data structures and a simple but effective
approach to object-oriented programming. Python is easy to learn."""words = text.split()
unique_words = set(words)
print(f"不同單詞數量: {len(unique_words)}")
練習2:共同興趣
# 找出兩個人的共同興趣
alice_interests = {"reading", "hiking", "coding", "movies"}
bob_interests = {"coding", "movies", "gaming", "cooking"}common_interests = alice_interests & bob_interests
print(f"共同興趣: {common_interests}")
練習3:集合運算
# 給定三個集合,找出只在A中出現的元素
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7}
C = {5, 6, 7, 8}result = A - (B | C)
print(f"只在A中的元素: {result}")
10. 總結
集合是Python中非常有用的數據結構,主要特點包括:
元素唯一性:自動去重
無序性:元素沒有固定順序
高效查找:基于哈希表實現,查找速度O(1)
關系運算:支持交集、并集、差集等數學運算
元素限制:只能包含不可變類型
掌握集合的使用可以:
簡化去重操作
提高查找效率
實現復雜的關系運算
優化程序性能
建議在實際編程中多嘗試使用集合,特別是需要去重或快速查找的場景。