掌握 Python 集合(Set)(14):靈活運用集合運算,提升資料處理效率

我們學會了如何創建集合,以及如何透過基礎操作來添加、刪除與檢查元素。這些是集合的基礎功。

然而,集合真正的威力在於它能進行數學上的集合運算,像是聯集、交集、差集與對稱差集。

這些操作不僅能幫助我們快速分析數據,還能應用在推薦系統、過濾資料與分類管理等實際情境中。

集合運算概述

集合運算是集合最強大的特性之一,讓我們可以執行各種集合數學操作:

聯集 (Union)

合併兩個集合中的所有元素(去重)

交集 (Intersection)

找出兩個集合中共有的元素

差集 (Difference)

找出僅在第一個集合中出現的元素

對稱差集 (Symmetric Difference)

找出僅在其中一個集合中出現的元素

這些操作對於數據分析、過濾和分類非常有用。

集合聯集操作

聯集操作返回一個包含兩個集合所有元素的新集合(去除重複項)。

使用 union() 方法

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

all_instruments = rock_songs.union(jazz_songs)
# 結果: {'guitar', 'drums', 'bass', 'saxophone', 'piano'}

使用 | 運算符

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

all_instruments = rock_songs | jazz_songs
# 結果: {'guitar', 'drums', 'bass', 'saxophone', 'piano'}

返回值的類型取決於左操作數的類型(set 或 frozenset)。

A simple 2-circle Venn diagram illustrating set union. Both circles overlap, and all areas (left, right, and overlap) are highlighted in blue to represent the union operation.

集合交集操作

交集操作返回一個僅包含兩個集合共有元素的新集合

使用 intersection() 方法

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

common = rock_songs.intersection(jazz_songs)
# 結果: {'drums'}

使用 & 運算符

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

common = rock_songs & jazz_songs
# 結果: {'drums'}

使用 intersection_update() 方法可以直接更新原始集合,而不是返回新集合:

rock_songs.intersection_update(jazz_songs)
# rock_songs 現在變為: {'drums'}

集合差集操作

差集操作返回一個僅包含在第一個集合但不在第二個集合中的元素的新集合

使用 difference() 方法

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

only_in_rock = rock_songs.difference(jazz_songs)
# 結果: {'guitar', 'bass'}

使用 – 運算符

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

only_in_jazz = jazz_songs - rock_songs
# 結果: {'saxophone', 'piano'}

使用 difference_update() 方法可以直接更新原始集合,而不是返回新集合:

rock_songs.difference_update(jazz_songs)
# rock_songs 現在變為: {'guitar', 'bass'}

集合對稱差集操作

對稱差集操作返回一個包含僅在一個集合中出現的元素的新集合(即兩個集合的並集減去它們的交集)。

使用 symmetric_difference() 方法

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

exclusive = rock_songs.symmetric_difference(jazz_songs)
# 結果: {'guitar', 'bass', 'saxophone', 'piano'}

使用 ^ 運算符

rock_songs = {'guitar', 'drums', 'bass'}
jazz_songs = {'saxophone', 'piano', 'drums'}

exclusive = rock_songs ^ jazz_songs
# 結果: {'guitar', 'bass', 'saxophone', 'piano'}

使用 symmetric_difference_update() 方法可以直接更新原始集合:

rock_songs.symmetric_difference_update(jazz_songs)
# rock_songs 現在變為: {'guitar', 'bass', 'saxophone', 'piano'}

案例研究:音樂推薦系統

讓我們使用集合來構建一個簡單的音樂推薦系統:

# 用戶喜歡的藝術家
user_likes = {'Taylor Swift', 'Ed Sheeran', 'Coldplay', 'Adele'}

# 相似藝術家數據庫
similar_to_taylor = {'Ed Sheeran', 'Katy Perry', 'Selena Gomez'}
similar_to_ed = {'John Mayer', 'Taylor Swift', 'Shawn Mendes'}
similar_to_coldplay = {'Imagine Dragons', 'OneRepublic', 'U2'}

# 找出用戶可能喜歡但尚未知道的藝術家
recommendations = (similar_to_taylor | similar_to_ed | similar_to_coldplay) - user_likes

print("推薦給您的藝術家:", recommendations)
# 輸出: {'Katy Perry', 'John Mayer', 'Selena Gomez', 'Imagine Dragons', 'OneRepublic', 'Shawn Mendes', 'U2'}
Music recommendation system showing related artists and genres connections in a network diagram

集合的限制

僅支持可哈希元素

集合只能包含不可變(可哈希)的元素,如數字、字符串、元組等。列表、字典和其他集合不能作為集合元素。

# 這會引發錯誤
my_set = {[1, 2], 'string'}  # TypeError

無序性

集合是無序的,不能通過索引訪問元素,也不保證元素的插入順序。如果順序很重要,考慮使用列表或有序字典。

不支持切片

由於集合沒有索引,因此不支持切片操作。

# 這會引發錯誤
my_set = {1, 2, 3, 4, 5}
subset = my_set[1:3]  # TypeError

瞭解這些限制有助於決定何時使用集合,何時選擇其他數據結構

集合與凍結集合:何時使用?

使用集合 (set) 的場景

  • 需要動態添加或刪除元素時
  • 進行數據去重操作
  • 需要頻繁執行集合運算(聯集、交集等)
  • 快速成員檢測(比列表更高效)
  • 臨時存儲不需要順序的唯一元素

使用凍結集合 (frozenset) 的場景

  • 需要集合作為字典的鍵
  • 需要集合作為另一個集合的元素
  • 確保數據不被意外修改
  • 作為函數參數,防止函數內部修改集合
  • 需要在多線程環境中安全共享的數據

選擇適合場景的數據結構可以提高代碼的效率、可讀性和安全性

結語

透過聯集、交集、差集與對稱差集,我們能快速完成複雜的資料比對與篩選,並在應用場景中建立像是推薦系統、內容過濾與高效檢索的功能。
此外,根據需求靈活選擇 set(可變)或 frozenset(不可變),能進一步提升程式的安全性與效率。

Python programming language logo floating above a set of unique colorful elements organized in a circular pattern

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端