Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonの「TypeError: unhashable type: 'dict'」エラーの原因と解決方法を徹底解説

Pythonでは、辞書(dictionary)のキーとして使用できるオブジェクトに厳格なルールがあります。Pythonの辞書では、すべてのキーが「ハッシュ可能(hashable)」である必要があります。

ハッシュ不可能な型をキーとして辞書に追加しようとすると、「TypeError: unhashable type: 'dict'」というエラーが発生します。

この記事では、このエラーの意味と発生理由を解説し、実際のコード例を通して、自分のコードでエラーを解決する方法を学びます。

TypeError: unhashable type: 'dict' とは何か

辞書は「キー」と「値」の2つの要素で構成されています。キーは値に紐づく識別子であり、キーを参照することで、そのキーに関連付けられた値を取得できます。

辞書のキーとして使用できるのは、ハッシュ可能なオブジェクトのみです。文字列、整数、タプル、frozensetなどのイミュータブル(変更不可能)なオブジェクトはハッシュ可能ですが、一部例外があります。そのため、辞書そのものを別の辞書のキーとして使うことはできません。

辞書にアイテムを追加するには、有効なハッシュ可能なキーを指定する必要があります。たとえば、"name" は有効なキーですが、{ "name": "test" } のような辞書はキーとして使用できません。

エラーが発生するコード例

ここでは、ベーカリーで5回以上売れたケーキを、ある辞書から別の辞書へ追加するプログラムを作成します。

まず、各ケーキの情報を格納した辞書のリスト「cakes」を宣言します。あわせて、5回以上売れたケーキを保存するための空の辞書も定義します。

cakes = [
	{
"name": "Black Forest Gateau", "sold": 3
},
{
"name": "Carrot Cake", "sold": 7
},
{
"name": "Coconut and Lime Cake", "sold": 9
}
]
sold_more_than_five = {}

「cakes」リストには3つの辞書が含まれています。各辞書には2つのキーと値があり、キー名は「name」と「sold」です。

次に、ケーキのリストを走査して、5回以上売れたケーキを見つけるforループを記述します。該当するケーキは「sold_more_than_five」辞書に追加されます。

for c in cakes:
	if c["sold"] > 5:
		sold_more_than_five[c] = c["sold"]
		print(c["name"] + " has been sold more than five times.")

print(sold_more_than_five)

このforループでは、各辞書の「sold」の値が5より大きいかどうかを判定します。条件を満たす場合、そのアイテムが「sold_more_than_five」辞書に追加され、そのケーキが5回以上売れたことを知らせるメッセージがコンソールに出力されます。

ループの実行後、「sold_more_than_five」辞書の内容をコンソールに出力します。

それでは、コードを実行してプログラムが正しく動作するか確認してみましょう。

Traceback (most recent call last):
  File "main.py", line 16, in <module>
	sold_more_than_five[c] = c["sold"]
TypeError: unhashable type: 'dict'

コードを実行すると、エラーが発生してしまいました。

エラーの解決方法

このコードが動作しない理由は、別の辞書を使って辞書のキーを作成しようとしているためです。

変数「c」の値は「cakes」リスト内の辞書そのものです。つまり、「sold_more_than_five」辞書にアイテムを追加しようとした際、気づかないうちに辞書をキーとして追加しようとしていたのです。

sold_more_than_five[c] = c["sold"]

if文が「Carrot Cake」に対して実行されるタイミングでは、コードは内部的に以下のような処理を行おうとしています。

sold_more_than_five[{"name": "Carrot Cake", "sold": 7}] = 7

これは無効な操作です。辞書を辞書のキーとして追加しようとしているためです。この問題は、c["name"] をキー名として使用するように変更することで解決できます。

sold_more_than_five[c["name"]] = c["sold"]

修正したコードで再度実行してみましょう。

Carrot Cake has been sold more than five times.
Coconut and Lime Cake has been sold more than five times.

{'Carrot Cake': 7, 'Coconut and Lime Cake': 9}

今度はコードが正常に実行されました。各ケーキの名前をキーとして使用するように変更したため、エラーが解消されたのです。

まとめ

「TypeError: unhashable type: 'dict'」エラーは、ハッシュ不可能なオブジェクトをキーとして辞書にアイテムを登録しようとしたときに発生します。辞書のキーとして使用できるのは、文字列、タプル、整数などのイミュータブルなオブジェクトのみです。

このエラーを解決するには、辞書にアイテムを追加する際に、必ずハッシュ可能なオブジェクトだけを使用するようにしましょう。これで、このよくあるPythonエラーもプロの開発者のように自信を持って解決できるはずです!

  1. Pythonの辞書メソッド一覧|使い方と機能をわかりやすく解説

    はじめに Pythonの辞書(dict)は、キーと値のペアでデータを管理できる非常に便利なデータ構造です。この記事では、辞書で直接使える辞書メソッドと、辞書の操作に役立つ組み込み関数を一覧表にまとめて紹介します。それぞれの機能を把握しておくと、日常的なコーディングの効率が大きく向上します。 辞書の主なメソッド一覧 以下は、Pythonの辞書オブジェクトで利用できる代表的なメソッドです。 No.メソッド名と説明 1dict.clear()辞書内のすべての要素(キーと値のペア)を削除します。 2dict.copy()辞書のコピー(浅いコピー)を作成して返します。 3dict.fromkeys(

  2. PythonでTypeError例外をキャッチ(捕捉)する方法

    PythonにおけるTypeErrorは、互換性のない型のオブジェクト同士を組み合わせた場合や、関数に想定外の型の引数を渡した場合に発生する例外です。例えば、リストと文字列を連結しようとしたり、数値を必要とする処理に文字列を渡したりすると、このエラーが発生します。TypeErrorの主な発生原因異なる型のオブジェクトを演算子で結合・操作した場合(例:リスト + 文字列)関数やメソッドに、期待される型と異なる型の引数を渡した場合整数と文字列など、比較できない型同士を比較した場合try-exceptを使ったTypeErrorの捕捉方法TypeErrorが発生してもプログラムを停止させずに処理を続行