Python の集合(作成方法と基本操作)
Python の集合(set)は、重複しない要素の集まりを表すデータ型だ。数学の集合論をベースにしており、要素の順序は保証されない。
リテラルと set() による作成
集合を作る方法は 2 つある。波括弧 {} を使うリテラル記法と、set() コンストラクタだ。
# リテラル記法
fruits = {"apple", "banana", "cherry"}
# set() コンストラクタ
numbers = set([1, 2, 3, 4, 5])
ただし、空の集合を作る場合は注意が必要になる。{} は空の辞書(dict)として解釈されるため、空の集合には set() を使う。
empty_dict = {} # これは辞書
empty_set = set() # これが空の集合
print(type(empty_dict)) # <class 'dict'>
print(type(empty_set)) # <class 'set'>
この仕様は Python 2 時代からの互換性によるものだ。辞書のリテラル {} が先に存在していたため、空の波括弧は辞書として扱われる。
重複の自動排除
集合に同じ値を複数入れても、重複は自動的に排除される。
numbers = {1, 2, 2, 3, 3, 3}
print(numbers) # {1, 2, 3}
リストから集合に変換すると、重複が除去された状態になる。これはデータのユニーク化によく使われるパターンだ。
items = ["a", "b", "a", "c", "b", "a"]
unique_items = set(items)
print(unique_items) # {'a', 'b', 'c'}
要素として格納できるもの
集合にはハッシュ可能(hashable)なオブジェクトのみ格納できる。具体的には、イミュータブル(不変)な型が対象となる。
int, float, str, tuple, frozenset, bool, None
list, dict, set(ミュータブルな型)
リストを集合に入れようとすると TypeError が発生する。
s = {[1, 2, 3]} # TypeError: unhashable type: 'list'
タプルは格納できるが、タプル内にリストが含まれる場合は不可だ。
s = {(1, 2, 3)} # OK
s = {(1, [2, 3])} # TypeError: unhashable type: 'list'
集合の基本情報
集合の要素数は len() で取得する。
s = {1, 2, 3, 4, 5}
print(len(s)) # 5
空かどうかの判定は、len() を使うか、集合をそのまま真偽値として評価できる。
s = set()
if not s:
print("集合は空")
if len(s) == 0:
print("集合は空")
Python では空のコレクションは偽(False)として評価されるため、if not s: という書き方が自然だ。
文字列からの集合作成
文字列を set() に渡すと、1 文字ずつ分解されて集合になる。
chars = set("hello")
print(chars) # {'h', 'e', 'l', 'o'}
重複する文字は 1 つにまとめられる。文字列中のユニークな文字を調べたいときに便利だ。
イテラブルからの変換
set() は任意のイテラブルを受け取れる。リスト、タプル、range、ジェネレータなど、反復可能なオブジェクトなら何でも変換できる。
# range から
s1 = set(range(5)) # {0, 1, 2, 3, 4}
# タプルから
s2 = set((1, 2, 3)) # {1, 2, 3}
# ジェネレータから
s3 = set(x * 2 for x in range(3)) # {0, 2, 4}
ジェネレータ式をそのまま渡せるため、メモリ効率を意識した集合作成も可能になる。