カテゴリ: Python 更新日: 2026/03/14

Pythonでセットを使うときに気をつけたい落とし穴!初心者でもわかる注意点ガイド

Pythonでセットを使うときに気をつけたい落とし穴
Pythonでセットを使うときに気をつけたい落とし穴

先生と生徒の会話形式で理解しよう

生徒

「先生、Pythonのセットを使ってみたけど、思わぬエラーが出たり、変な結果になったりしました。セットを使うときに気をつけることってありますか?」

先生

「セットは便利ですが、使うときに知っておきたいポイントや落とし穴があります。今回は、初心者の方がつまずきやすいところをわかりやすく解説しますね。」

生徒

「ぜひ教えてください!どんなことに気をつければいいですか?」

先生

「それでは順番に見ていきましょう!」

1. セット(set)は「重複を自動で削除」するが「順番」はバラバラ

1. セット(set)は「重複を自動で削除」するが「順番」はバラバラ
1. セット(set)は「重複を自動で削除」するが「順番」はバラバラ

Pythonのセット(set)という機能の最大の特徴は、「同じ値を2つ以上持てない」という点です。これを「重複を許さない」と呼びます。例えば、名簿を作るときにうっかり同じ名前を2回登録しても、セットを使えば自動的に1人分にまとめてくれるので、データの整理にとても便利です。

ただし、大きな落とし穴があります。セットはリスト(list)と違って、データの並び順を管理していません。「1番目に入れたから最初に表示される」というルールがないため、中身を取り出すたびに順番が入れ替わってしまう可能性があるのです。そのため、特定の順番で処理したい場合には向いていません。


# 同じ「りんご」を2つ入れてみます
fruits = {"りんご", "みかん", "バナナ", "りんご"}

# 表示すると「りんご」は1つだけになり、順番も入れ替わることがあります
print(fruits)

# 実行結果の例(実行するたびに変わるかもしれません)
# {'みかん', 'バナナ', 'りんご'}

プログラミング未経験の方によくあるミスとして、セットをリストと同じ感覚で使ってしまい、「さっきと表示順が違う!」と驚くケースがあります。「重複は消えるが、並び順は運任せ」というセットの個性をしっかり覚えておきましょう。

2. セットの要素には「変更できないデータ」だけ使える

2. セットの要素には「変更できないデータ」だけ使える
2. セットの要素には「変更できないデータ」だけ使える

Pythonのセット(set)には、どんなデータでも自由に入れられるわけではありません。実は、「中身を後から書き換えられないデータ(イミュータブル)」という決まった種類のデータしか入れることができないルールがあります。

例えば、数字や文字列、タプルなどは一度作成するとその値を変更できないため、セットの要素として使うことができます。一方、中身を自由に入れ替えられる「リスト」や「辞書」は、セットに入れようとするとエラーが発生してしまいます。

【初心者向け:イミュータブルとは?】
「イミュータブル(Immutable)」は、日本語で「不変」という意味です。セットは、それぞれの要素が「何であるか」を厳密に管理して重複を防いでいるため、途中で中身が変わってしまう可能性があるデータ(リストなど)は受け付けない仕組みになっています。

# 〇 OKな例:数値、文字列、タプル(変更できないデータ)
my_set = {100, "Python学習", (1, 2, 3)}
print(my_set)

# × NGな例:リスト(変更できるデータ)を入れようとする
# error_set = {1, 2, [3, 4]}  
# 実行すると「TypeError: unhashable type: 'list'」というエラーになります

プログラミング未経験の方は、「セットの中身は、後から勝手に形が変わらない安定したものしか入れられない」というイメージで覚えておくと、エラーに直面したときにスムーズに対処できるようになります。この性質を専門用語で「ハッシュ可能(Hashable)」と呼ぶこともありますが、まずは「変更不可=OK」とシンプルに理解しておきましょう。

3. セットの中にリストや辞書を入れようとするとエラーになる

3. セットの中にリストや辞書を入れようとするとエラーになる
3. セットの中にリストや辞書を入れようとするとエラーになる

セットにリストや辞書を入れると、Pythonは「TypeError」というエラーを出します。これは、リストや辞書が「変更可能」なのでセットの仕組みと合わないからです。

もしエラーが出たら、セットに入れようとしている要素がイミュータブルかどうか確認してみましょう。


# エラーになる例
# my_set = {1, [2, 3]}  # TypeError: unhashable type: 'list'

# 辞書をセットに入れる例(エラー)
# my_set = {{"a": 1}}  # TypeError: unhashable type: 'dict'

4. セットは順序がないのでインデックスでアクセスできない

4. セットは順序がないのでインデックスでアクセスできない
4. セットは順序がないのでインデックスでアクセスできない

リストと違い、セットは「順序を持たない」ため、fruits[0]のように番号で特定の要素を取り出すことはできません。

セットの要素を1つずつ処理したいときは、forループで順番を気にせずに回す方法を使います。


fruits = {"りんご", "みかん", "バナナ"}

# エラーになる例
# print(fruits[0])  # TypeError

# 正しい使い方(ループで全要素を表示)
for fruit in fruits:
    print(fruit)

5. 空のセットを作るときは注意が必要!

5. 空のセットを作るときは注意が必要!
5. 空のセットを作るときは注意が必要!

空のセットを作るには、set()と書きます。{}と書くと空の辞書(キーと値のペア)になるので、間違いやすいです。


# 空のセット
empty_set = set()

# 空の辞書
empty_dict = {}

print(type(empty_set))  # <class 'set'>
print(type(empty_dict))  # <class 'dict'>

6. セットの要素は順序が変わることがあるので注意

6. セットの要素は順序が変わることがあるので注意
6. セットの要素は順序が変わることがあるので注意

セットの要素は保存順序が保証されていません。特にプログラムの動作環境やPythonのバージョンが変わると、要素の順番も変わる可能性があります。

そのため、セットの順序に頼った処理を書くのは避けましょう。順序が大事な場合はリストやタプルを使うのがおすすめです。

7. セットの使い方に慣れておくとプログラムが効率的になる

7. セットの使い方に慣れておくとプログラムが効率的になる
7. セットの使い方に慣れておくとプログラムが効率的になる

セットは重複を自動で除いてくれるので、データの重複チェックや集合演算(和・積・差)に便利です。ただし、今回説明した注意点を守らないとエラーや思わぬ動作の原因になることがあります。

これらのポイントを理解して、セットを安心して使えるようになりましょう。

まとめ

まとめ
まとめ

ここまでPythonのセット(set型)における基本的な使い方から、初心者が陥りやすい「落とし穴」までを詳しく見てきました。セットは、リスト(list)や辞書(dict)と並んでPythonの標準的なデータ構造の一つですが、その性質は非常に独特です。

セットの大きな特徴と活用場面

まず、セットの最大の特徴は「重複を一切許さない」という点にあります。これを利用すると、大量のデータから重複している値を取り除く作業が、たった一行のコードで完結します。例えば、Webサイトの訪問者のIPアドレスのリストからユニークなユーザー数を知りたい場合や、アンケート結果から回答の種類のバリエーションを抽出したい場合などに非常に有効です。

また、セットは数学的な「集合演算」が得意です。二つのデータ群を比較して、「両方に共通するもの(積集合)」、「どちらか一方にしかないもの(差集合)」、「両方を合わせた全データ(和集合)」などを瞬時に計算できます。これはデータの整合性をチェックする際や、特定の条件に合致するユーザーを絞り込む際などに威力を発揮します。

注意すべき「ミュータブル」と「イミュータブル」

記事の中でも触れた通り、セットには「変更可能なオブジェクト(ミュータブルなオブジェクト)」を要素として入れることができません。これはPythonの内部で「ハッシュ値」というものを使ってデータを高速に管理しているためです。リストや辞書は、中身を後から書き換えることができるため、このハッシュ値が安定せず、セットの要素としては適さないのです。

もし「セットの中に複数の情報をまとめたい」という場合は、リストではなく、タプル(tuple)を使用することを検討してください。タプルは中身を変更できない(イミュータブルな)型であるため、セットの要素として安全に格納することができます。

実践的なコード例:重複削除とデータ変換

実際の開発現場でよく使われる、リストから重複を削除して再びリストに戻す手順をおさらいしておきましょう。この手法は、Pythonエンジニアにとって非常にポピュラーなテクニックです。


# 重複のあるユーザーIDのリスト
user_ids = ["U001", "U002", "U001", "U003", "U002", "U004"]

# セットに変換して重複を自動削除
unique_ids_set = set(user_ids)

# 再びリストに戻す(必要に応じて)
unique_ids_list = list(unique_ids_set)

print("重複削除後のリスト:")
print(unique_ids_list)

実行結果は以下のようになります。


重複削除後のリスト:
['U003', 'U004', 'U002', 'U001']

ここで注目すべきは、実行結果の順番です。元のリストでは "U001" が先頭でしたが、セットを経由したことで順番が入れ替わっています。このように、「セットを使うと順序がバラバラになる可能性がある」という点は、常に意識しておく必要があります。

空のオブジェクト生成における「{}」の正体

もっとも間違いやすいポイントの一つが、空のセットの作り方です。Pythonにおいて {} は歴史的に辞書(dict)を表すための記号として使われてきました。そのため、後から追加されたセット型では set() という専用の関数を使うルールになっています。


# 間違えやすい初期化
data_container = {} 

if isinstance(data_container, dict):
    print("これは辞書型です。")
else:
    print("これはセット型です。")

これは辞書型です。

プログラミングを始めたばかりの頃は、つい {} と書いてしまいがちですが、これによって予期せぬ KeyError などのエラーを招くこともあります。セットを新しく作るときは set() を使う癖をつけましょう。

セットを使いこなすためのステップ

Pythonのセットは、決して「使いにくい型」ではありません。むしろ、その制限(順序がない、変更可能な要素はNGなど)を理解していれば、これほど頼もしいツールはありません。特に計算速度の面では、リストの中から特定の要素を探すよりも、セットの中から探す方が圧倒的に高速であるというメリットもあります。

まずは、「重複させたくないデータがあるとき」や「二つのグループを比較したいとき」に、積極的にセットを使ってみることから始めてみてください。失敗してエラーが出たとしても、それが「イミュータブルかどうか」を確認する良い練習になるはずです。

先生と生徒の振り返り会話

生徒

「先生、まとめを読んで改めてセットの個性が分かりました。特に『リストをセットに入れるとエラーになる』っていうのは、中身が書き換えられるもの(ミュータブル)を入れちゃダメっていうルールがあるからなんですね。」

先生

「その通りです!よく理解できましたね。ハッシュ値という一意の鍵でデータを管理しているからこそ、中身が変わってしまうリストはセットにとって困る存在なんです。もし複数のデータをひとまとめにしてセットに入れたい時はどうすればいいか覚えていますか?」

生徒

「はい、タプルを使えばいいんですよね。タプルなら中身が変更できないから、セットの要素としても安全に扱えるって学びました。あと、空のセットを set() で作るのも忘れないようにします。{} だと辞書になっちゃうのは、最初ハマりそうなポイントですね。」

先生

「素晴らしい!セットの最大活用シーンである『重複削除』も、実務で本当によく使います。ただし、順番がぐちゃぐちゃになることだけは常に頭の片隅に置いておいてくださいね。順番が大事なときは、やっぱりリストが一番です。」

生徒

「使い分けが大事なんですね。重複チェックはセット、順番保持はリスト。状況に合わせて使いこなせるように練習してみます!」

先生

「その意気です。Pythonにはいろんな便利なデータ型がありますが、それぞれの個性を知ることで、より効率的で読みやすいコードが書けるようになりますよ。また分からないことがあればいつでも聞いてくださいね。」

カテゴリの一覧へ
新着記事
New1
Python
Pythonの関数を引数に渡す方法を初心者向けにやさしく解説!高階関数の使い方も完全ガイド
New2
Python
Pythonのクロージャー(Closure)とは?関数内関数とnonlocalの活用
New3
Python
Pythonのスコープとは?ローカル変数・グローバル変数の違いと使い分け
New4
Python
Pythonのreturn文の使い方!値を返す関数の書き方と注意点
人気記事
No.1
Java&Spring記事人気No1
Python
Pythonでトランザクション処理を実装する方法を完全解説!commit・rollbackで安全なSQL操作
No.2
Java&Spring記事人気No2
Python
Pythonの文字列を1文字ずつ処理する方法!for文やlist化の活用例
No.3
Java&Spring記事人気No3
Flask
FlaskでAPIのレスポンスをキャッシュ!通信負荷を軽減して爆速にする方法
No.4
Java&Spring記事人気No4
Flask
Flaskとは何か?初心者向けにできること・特徴・インストール手順までやさしく解説
No.5
Java&Spring記事人気No5
Flask
Flaskでデータベースエラーを処理する方法!初心者にもわかる例外の使い方
No.6
Java&Spring記事人気No6
Flask
FlaskのSQLAlchemyでフィルタリング検索!filter, filter_byの使い方完全ガイド
No.7
Java&Spring記事人気No7
Python
Pythonの文字列から一部を抽出する方法!スライスを使った基本的な切り出し方
No.8
Java&Spring記事人気No8
Flask
Flaskで開発中にデータベースを初期化する方法!初心者でもわかる便利なTips