Python学習チャンネル by PyQ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonのset型(集合型)で、要素のオブジェクトが重複しない理由を解説します

f:id:kenken0326:20210616111445p:plain

こんにちは。PyQチームのtsutomuです。
今回は「集合を扱うデータ型のsetで、要素のオブジェクトが重複しない理由」を解説します。

質問:setを使うとなぜオブジェクトが重複しないのか?

Pythonのsetを使って、下記のように、2回オブジェクト(以下では123)を追加しました。しかし出力すると{123}のように1つしかありません。なぜ、そうなるのか詳しく教えてください。

set1 = set()  # 空のset
set1.add(123)
set1.add(123)  # 同じオブジェクトを追加
print(set1)  # 1つだけ「{123}」と出力

回答:setが重複しない理由

setは集合を表すデータ構造です。重複しない要素の集まりを表現するための型なので、同じオブジェクトを複数持つことはできません。

setでは、オブジェクトが追加されるときに「既に同じオブジェクトがあるかどうか」を確認して、異なるオブジェクトだけが追加されます。

それはオブジェクトを追加するときに、既に同じオブジェクトがあるかを確認して、異なるオブジェクトだけを追加するからです。

同じオブジェクトかを確認するには、ハッシュ値を使って効率的に確認できるようになっています。

ハッシュ値は、ハッシュ関数(hash())を使って計算します。

print(hash(123))  # 123
print(hash('123'))  # -3322108026846747911

ハッシュ関数は、上記のようにオブジェクトを引数にして整数のハッシュ値を求める関数です。-3322108026846747911というハッシュ値は、Pythonを起動するたびに値が異なることに注意してください(Pythonを起動している間はハッシュ値は変わりません)。

仮に、異なるオブジェクトのハッシュ関数が同じ値になっても問題ありません。ハッシュ値が同じオブジェクトは、さらに同値かどうかを比較します。追加しようとしたオブジェクトが、既に存在するオブジェクトと異なる値であれば、別のオブジェクトと判断され追加されます。

なお、ハッシュ関数で計算できないオブジェクトは、そもそもsetに追加できません。
たとえば、変更可能(ミュータブル)なオブジェクトであるリストは、以下のようにhash()を使うとエラーになります。つまり、リストはsetに追加できません。

hash([])  # TypeError: unhashable type: 'list'

ハッシュ可能なオブジェクトには、数値や文字列などがあります。
また、リストはハッシュ可能ではありませんが、(ハッシュ可能な要素を持つ)タプルはハッシュ可能です。

エラー「TypeError: unhashable type: 'list'」については下記の記事も参考にしてください

blog.pyq.jp

setについては下記も参考にしてください

関連するクエスト

このお悩み解決はPyQのクエスト「setのメソッドの使い方を学ぼう」の1問目の補足情報として作成しています。

Copyright ©2017- BeProud Inc. All rights reserved.