Pythonのset型で集合演算をマスター【和集合・積集合・部分集合完全ガイド】
Pythonのset型は、数学の集合論を直感的にプログラムで扱える優れたデータ型です。この記事では、和集合、積集合、部分集合の判定など、set型の全機能を実践的なサンプルコードと共に詳しく解説します。
set型の基本
セットの作成方法
# 基本的な作成方法
set1 = {1, 2, 3, 4, 5}
set2 = set([1, 2, 3, 4, 5]) # リストから作成
set3 = set("hello") # 文字列から作成 {'h', 'e', 'l', 'o'}
print(set1) # {1, 2, 3, 4, 5}
print(set3) # {'h', 'e', 'l', 'o'}
空のセットと重複の除去
# 空のセット
empty_set = set() # 空のセット
# empty_set = {} # これは辞書!
# 重複要素の自動除去
duplicate_list = [1, 2, 2, 3, 3, 3, 4]
unique_set = set(duplicate_list)
print(unique_set) # {1, 2, 3, 4}
基本的なセット操作
要素の追加と削除
fruits = {"apple", "banana", "orange"}
# 要素の追加
fruits.add("grape")
print(fruits) # {'apple', 'banana', 'orange', 'grape'}
# 複数要素の追加
fruits.update(["mango", "kiwi"])
print(fruits)
# 要素の削除
fruits.remove("banana") # エラーが出る可能性あり
fruits.discard("cherry") # エラーが出ない
popped = fruits.pop() # ランダムに削除
セットの長さと存在確認
numbers = {1, 3, 5, 7, 9}
# セットのサイズ
size = len(numbers) # 5
print(f"要素数: {size}")
# 要素の存在確認
print(3 in numbers) # True
print(4 in numbers) # False
print(6 not in numbers) # True
和集合(Union)
union()メソッドと|演算子
set_a = {1, 2, 3}
set_b = {3, 4, 5}
# union()メソッド
union1 = set_a.union(set_b)
print(union1) # {1, 2, 3, 4, 5}
# |演算子
union2 = set_a | set_b
print(union2) # {1, 2, 3, 4, 5}
# 複数セットの和集合
set_c = {5, 6, 7}
union3 = set_a | set_b | set_c
print(union3) # {1, 2, 3, 4, 5, 6, 7}
update()による和集合の代入
set_a = {1, 2, 3}
set_b = {3, 4, 5}
# 元のセットを変更
set_a.update(set_b) # set_a |= set_b と同等
print(set_a) # {1, 2, 3, 4, 5}
積集合(Intersection)
intersection()メソッドと&演算子
set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}
# intersection()メソッド
intersection1 = set_a.intersection(set_b)
print(intersection1) # {3, 4}
# &演算子
intersection2 = set_a & set_b
print(intersection2) # {3, 4}
# 複数セットの積集合
set_c = {2, 3, 4, 7}
intersection3 = set_a & set_b & set_c
print(intersection3) # {3, 4}
共通要素の存在確認
set_a = {1, 2, 3}
set_b = {4, 5, 6}
set_c = {2, 4, 6}
# 共通要素があるかチェック
print(set_a.isdisjoint(set_b)) # True(共通要素なし)
print(set_a.isdisjoint(set_c)) # False(共通要素あり)
差集合(Difference)
difference()メソッドと-演算子
set_a = {1, 2, 3, 4, 5}
set_b = {3, 4, 5, 6, 7}
# difference()メソッド
diff1 = set_a.difference(set_b)
print(diff1) # {1, 2}
# -演算子
diff2 = set_a - set_b
print(diff2) # {1, 2}
# 逆方向の差集合
diff3 = set_b - set_a
print(diff3) # {6, 7}
差集合の代入
set_a = {1, 2, 3, 4, 5}
set_b = {3, 4, 5}
# 元のセットから要素を除去
set_a.difference_update(set_b) # set_a -= set_b と同等
print(set_a) # {1, 2}
対称差集合(Symmetric Difference)
symmetric_difference()メソッドと^演算子
set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}
# symmetric_difference()メソッド
sym_diff1 = set_a.symmetric_difference(set_b)
print(sym_diff1) # {1, 2, 5, 6}
# ^演算子
sym_diff2 = set_a ^ set_b
print(sym_diff2) # {1, 2, 5, 6}
# 対称差集合は (A-B) ∪ (B-A) と同じ
manual_sym_diff = (set_a - set_b) | (set_b - set_a)
print(manual_sym_diff) # {1, 2, 5, 6}
部分集合・上位集合の判定
subset(部分集合)の判定
set_a = {1, 2, 3}
set_b = {1, 2, 3, 4, 5}
set_c = {1, 2, 3}
# 部分集合の判定
print(set_a.issubset(set_b)) # True(AはBの部分集合)
print(set_a <= set_b) # True(同上)
# 真部分集合の判定
print(set_a < set_b) # True(AはBの真部分集合)
print(set_a < set_c) # False(同じセット)
superset(上位集合)の判定
set_a = {1, 2, 3, 4, 5}
set_b = {2, 3}
# 上位集合の判定
print(set_a.issuperset(set_b)) # True(AはBの上位集合)
print(set_a >= set_b) # True(同上)
# 真上位集合の判定
print(set_a > set_b) # True(AはBの真上位集合)
frozenset(不変セット)
frozensetの基本
# 不変セットの作成
frozen_set = frozenset([1, 2, 3, 4])
print(frozen_set) # frozenset({1, 2, 3, 4})
# セットの要素としてfrozensetを使用
set_of_sets = {
frozenset([1, 2]),
frozenset([3, 4]),
frozenset([1, 2]) # 重複は除去される
}
print(set_of_sets)
frozensetと通常setの演算
normal_set = {1, 2, 3}
frozen_set = frozenset([2, 3, 4])
# 演算結果は通常set
union = normal_set | frozen_set
print(type(union)) # <class 'set'>
print(union) # {1, 2, 3, 4}
実践的な応用例
重複データの検出
def find_duplicates(data_list):
seen = set()
duplicates = set()
for item in data_list:
if item in seen:
duplicates.add(item)
else:
seen.add(item)
return duplicates
data = [1, 2, 3, 2, 4, 5, 3, 6]
dups = find_duplicates(data)
print(f"重複要素: {dups}") # {2, 3}
ユーザー権限の管理
class UserPermissions:
def __init__(self, user_id):
self.user_id = user_id
self.permissions = set()
def grant_permission(self, permission):
self.permissions.add(permission)
def revoke_permission(self, permission):
self.permissions.discard(permission)
def has_permission(self, permission):
return permission in self.permissions
def has_all_permissions(self, required_permissions):
return required_permissions.issubset(self.permissions)
# 使用例
user = UserPermissions("user001")
user.grant_permission("read")
user.grant_permission("write")
required = {"read", "write", "admin"}
print(user.has_all_permissions(required)) # False
データベースの差分検出
def database_diff(old_records, new_records):
old_set = set(old_records)
new_set = set(new_records)
added = new_set - old_set
deleted = old_set - new_set
common = old_set & new_set
return {
'added': added,
'deleted': deleted,
'unchanged': common
}
old_data = ['user1', 'user2', 'user3']
new_data = ['user2', 'user3', 'user4', 'user5']
diff = database_diff(old_data, new_data)
print(f"追加: {diff['added']}") # {'user4', 'user5'}
print(f"削除: {diff['deleted']}") # {'user1'}
print(f"変更なし: {diff['unchanged']}") # {'user2', 'user3'}
性能特性と注意点
セットの検索速度
import time
# リストでの検索(O(n))
large_list = list(range(10000))
start = time.time()
result = 9999 in large_list
end = time.time()
print(f"リスト検索時間: {end-start:.6f}秒")
# セットでの検索(O(1))
large_set = set(range(10000))
start = time.time()
result = 9999 in large_set
end = time.time()
print(f"セット検索時間: {end-start:.6f}秒")
ハッシュ可能な要素のみ
# ハッシュ可能な要素
valid_set = {1, "text", (1, 2), frozenset([3, 4])}
# ハッシュ不可能な要素(エラーになる)
try:
invalid_set = {[1, 2, 3]} # リストは不可
except TypeError as e:
print(f"エラー: {e}")
try:
invalid_set = {{1, 2, 3}} # セットは不可
except TypeError as e:
print(f"エラー: {e}")
まとめ
Pythonのset型は以下の特徴を持つ優れたデータ型です:
- 重複を自動的に除去
- 高速な要素検索(O(1))
- 直感的な集合演算
- 数学的な集合論の完全実装
データの重複除去、集合演算、高速検索が必要な場面では、set型を積極的に活用しましょう。特にデータ分析、権限管理、差分検出などの実用的な場面で威力を発揮します。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座


