Python

【Python】辞書のキーには列挙型(enum)がおすすめである3つの理由

2022年10月15日

※ 本ブログはプロモーションが含まれています

【Python】辞書のキーには列挙型(enum)がおすすめである3つの理由

ポロシャツエンジニア

3分で技術が身に付くブログ!
・ポロシャツを愛するエンジニア
・企業にて研究開発職
・画像処理 | Deep Learning

Pythonにて、辞書のキーには列挙型(enum)をおすすめする3つの理由を紹介します!

おすすめの読者

  • 辞書型・列挙型(enum)を活用したい方
  • 辞書型のキーを効率良く管理したい方
  • 辞書型へのアクセスを効率化したい方

【結論】辞書のキーには列挙型(enum)を活用すべき!

結論、辞書のキーには列挙型(enum)を活用すべきです
本記事の内容を深く理解するためには、 入門 Python 3 Effective Python Pythonプログラムを改良する90項目 がおすすめです!

理由3選

  • 辞書のキーの要件はイミュータブルなオブジェクトであるため!
  • 辞書のキーを列挙型で管理することができるため!
  • 列挙型のvalue値の変更に柔軟に対応できるため!

【理由】辞書のキーには列挙型(enum)を活用すべき3つの理由

辞書のキーの要件はイミュータブルなオブジェクト!

Pythonの辞書のキーはイミュータブル(変更不可のオブジェクト)であることが要件です!
そのため、イミュータブルオブジェクトであるenumは辞書のキーに活用することができます!

下記例では、列挙型にて人の名前を管理するクラスを定義し、各人の年齢を辞書型にて管理することを実現します。

  • 10行目:辞書のキー名を管理するための列挙型を定義
  • 20行目:列挙型を辞書のキーにして、値を格納
  • 27行目:列挙型を辞書のキーに、値にアクセス
$ ipython
Python 3.9.12 (main, Jul 30 2022, 16:42:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import enum

# 辞書のキー名を管理するための列挙型を定義
In [2]: class Member(enum.Enum):
   ...:     TARO = enum.auto()
   ...:     JIRO = enum.auto()
   ...:     GORO = enum.auto()
   ...:

# 辞書を定義
In [3]: member_age = {}

# `Member`クラスを辞書のキーに
In [4]: member_age[Member.TARO] = 20
In [5]: member_age[Member.JIRO] = 25

In [6]: member_age.items()
Out[6]: dict_items([(<Member.TARO: 1>, 20), (<Member.JIRO: 2>, 25)])

# 辞書の要素にアクセス
In [7]: member_age[Member.TARO]
Out[7]: 20

# 未定義のキーにアクセス
In [8]: member_age[Member.GORO]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In [8], line 1
----> 1 member_age[Member.GORO]

KeyError: <Member.GORO: 3>

辞書のキーを列挙型で管理することができるため!

列挙型を活用することで、Pythonの辞書のキーに型アノテーションを付与することができます!
これにより、辞書のキー候補を予め把握することができます

  • 17行目:辞書の宣言時に列挙型がキーであることを型アノテーション
  • 20行目:列挙型を辞書のキーにして、値を格納
  • 27行目:列挙型を辞書のキーに、値にアクセス
$ ipython
Python 3.9.12 (main, Jul 30 2022, 16:42:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import enum
In [2]: import typing

# 辞書のキー名を管理するための列挙型を定義
In [3]: class Member(enum.Enum):
   ...:     TARO = enum.auto()
   ...:     JIRO = enum.auto()
   ...:     GORO = enum.auto()
   ...:

# 辞書のキーが`Member`であることを型アノテーション
In [4]: member_age: typing.Dict[Member, int] = {}

# `Member`クラスを辞書のキーに
In [5]: member_age[Member.TARO] = 20
In [6]: member_age[Member.JIRO] = 25

In [7]: member_age.items()
Out[7]: dict_items([(<Member.TARO: 1>, 20), (<Member.JIRO: 2>, 25)])

# 列挙型を活用して、辞書の要素にアクセス
In [8]: member_age[Member.TARO]
Out[8]: 20

列挙型のvalue値の変更に柔軟に対応できるため!

列挙型のvalue値が変更になった場合でも、柔軟に辞書の活用ができることもおすすめの点です!

列挙型の値に、各メンバーの居住している都道府県名を指定するとします。

  • 10行目:辞書のキー名を管理するための列挙型を定義、値には居住する都道府県名
  • 20行目:列挙型を辞書のキーにして、値を格納
  • 27行目:列挙型を辞書のキーに、値にアクセス
$ ipython
Python 3.9.12 (main, Jul 30 2022, 16:42:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import enum
In [2]: import typing

# 辞書のキー名を管理するための列挙型を定義、値には居住する都道府県名
In [3]: class MemberPrefecture(enum.Enum):
   ...:     TARO = "TOKYO"
   ...:     JIRO = "TOKYO"
   ...:     GORO = "OSAKA"
   ...:

# 辞書のキーが`MemberPrefecture`であることを型アノテーション
In [4]: member_age: typing.Dict[MemberPrefecture, int] = {}

# `MemberPrefecture`クラスを辞書のキーに
In [5]: member_age[Member.TARO] = 20
In [6]: member_age[Member.JIRO] = 25

In [7]: member_age.items()
Out[7]: dict_items([(<Member.TARO: "TOKYO">, 20), (<Member.JIRO: "TOKYO">, 25)])

# 列挙型を活用して、辞書の要素にアクセス
In [8]: member_age[Member.TARO]
Out[8]: 20

# 列挙型を活用して、辞書の要素にアクセス
In [9]: member_age[Member.JIRO]
Out[9]: 25

【比較】辞書のキーが文字列と列挙型であるときの違い

辞書のキーが文字列と列挙型(enum)であるときの違いについて、解説します。

文字列を使用した場合は、キーの候補が無限に存在するため、keys()等を活用して、キー名を取得する必要性があります。
そのため、辞書のキー管理が煩雑化することが想定されます。

一方、列挙型の場合は、定義された列挙型の各要素が辞書のキー候補であるため、管理が容易となります。

  • 9行目:文字列をキーとする辞書を定義
  • 12行目:文字列を辞書のキーにして、値を格納
  • 17行目:キーが文字列であるため、候補は無限大、`keys()`にてキー名取得
  • 21行目:文字列を辞書のキーに、値にアクセス
$ ipython
Python 3.9.12 (main, Jul 30 2022, 16:42:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import typing

# 辞書のキーが文字列であることを型アノテーション
In [2]: member_age: typing.Dict[str, int] = {}

# 文字列を辞書のキーに
In [3]: member_age["TARO"] = 20
In [4]: member_age["JIRO"] = 25

# 辞書のキー名は文字列であるため、候補が分からない
# `keys()`で辞書のキー名を取得する
In [5]: member_age.keys()
Out[5]: dict_items(["TARO", 20), ("JIRO", 25)])

# 文字列を活用して、辞書の要素にアクセス
In [6]: member_age["TARO"]
Out[6]: 20

【まとめ】辞書のキーには列挙型(enum)を活用すべき!

結論、辞書のキーには列挙型(enum)を活用すべきです
本記事の内容を深く理解するためには、 入門 Python 3 Effective Python Pythonプログラムを改良する90項目 がおすすめです!

理由3選

  • 辞書のキーの要件はイミュータブルなオブジェクトであるため!
  • 辞書のキーを列挙型で管理することができるため!
  • 列挙型のvalue値の変更に柔軟に対応できるため!


初心者にはこちらがおすすめ!
中級・上級者にはこちらがおすすめ!
  • この記事を書いた人

ポロシャツエンジニア

3分で技術が身に付くブログ!
・ポロシャツを愛するエンジニア
・企業にて研究開発職
・画像処理 | Deep Learning

-Python