このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】階層的なデータ構造を作る

階層的なデータ構造を作る

 現実のシステムでは、単一のデータ構造だけで表現できない複雑な情報を扱う必要があります。Pythonでは、リスト、タプル、辞書などの基本的なデータ構造を組み合わせることで、複数の階層にわたるデータの整理や操作が可能です。
 ここでは、各データ構造の特徴を活かし、どのようにして効率的なデータ管理を実現するのかを、実例を通して解説します。なお、以下の例では「会社の部門ごとの社員データ管理」というテーマを用いて、部門をキーとした辞書の中に社員情報のリスト、そして各社員の情報をタプルで表現する方法を紹介します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.階層的データ構造の基本概念

1.1. 主要なデータ構造とその特徴

Pythonでよく使われるデータ構造には以下のものがあります。

データ構造の比較表

データ構造特徴用途
タプル不変で要素数が固定社員の名前、年齢、役職など、変更する必要のない情報の格納
リスト要素の追加・変更・削除が可能部門ごとの社員一覧など、頻繁に更新が行われるデータの管理
辞書キーと値のペアでデータを保持。キーで直接アクセス可能部門名をキーとして、複数のリスト(社員データ)を管理

 これらのデータ構造を組み合わせることで、たとえば「部門ごとの社員情報」という階層的な構造が作れ、用途に合わせた最適な操作が実現できます。

1.2. 複合データ構造を使うメリット

複数のデータ構造を組み合わせる主なメリットは以下の通りです。

  • 効率的な管理
    各階層で最適なデータ構造を用いることで、データの追加、削除、変更といった操作を効率良く行えます。
  • 明確な役割分担
    たとえば、部門の一覧は辞書で管理し、その中の社員リストはリストで管理、個々の社員情報はタプルで保持することで、それぞれのデータの性質に応じた扱いが可能です。
  • 読みやすいコード
    複雑な情報を階層ごとに整理することで、コード全体の見通しが良くなり、保守性も向上します。

2.会社の部門ごとの社員データ管理の例

 ここでは、実際に部門ごとの社員データを階層的に管理するプログラム例を示します。以下の例では、辞書を用いて部門名をキーにし、各部門の社員情報(タプルのリスト)を値として格納しています。

2.1. データ構造の作成

まずは、初期状態として各部門の社員情報をまとめたデータ構造を作成します。

サンプルプログラム

# 会社の部門ごとの社員データを管理する例
# ・辞書: 部門名をキーとして社員リストを保持
# ・リスト: 各部門内の社員情報を格納
# ・タプル: 個々の社員情報 (名前, 年齢, 役職) を表す

company = {
    '営業': [('山田太郎', 35, '部長'), ('鈴木花子', 29, '営業担当')],
    '開発': [('佐藤次郎', 32, 'リードエンジニア'), ('高橋三郎', 27, 'プログラマー')]
}

# 初期状態の会社データを表示
print("初期の会社データ:")
print(company)

実行結果

初期の会社データ:
{'営業': [('山田太郎', 35, '部長'), ('鈴木花子', 29, '営業担当')], '開発': [('佐藤次郎', 32, 'リードエンジニア'), ('高橋三郎', 27, 'プログラマー')]}

解説

  • 辞書companyのキーは部門名(例:'営業', '開発')です。
  • 各部門の値はリストであり、その中に複数のタプルが格納されています。
  • 各タプルは、社員の名前、年齢、役職を順に持っており、固定的な情報として管理されます。

2.2. データの追加と取り出し

次に、新たな社員の追加方法や、既存データから特定の情報を取り出す方法を解説します。

サンプルプログラム

# 新しい社員を「開発」部に追加する例
# appendメソッドを使用する際、社員情報は一つのタプルとして渡す必要があります。
company['開発'].append(('伊藤四郎', 30, 'プログラマー'))
print("\n新しい社員を追加後の開発部のデータ:")
print(company['開発'])

# 営業部の2番目の社員情報を取得して、アンパッキングで各情報に分解する例
employee = company['営業'][1]  # インデックス1は「鈴木花子」のデータ
name, age, position = employee
print(f"\n{employee[0]}さんの詳細:")
print(f"名前: {name}, 年齢: {age}, 役職: {position}")

実行結果

新しい社員を追加後の開発部のデータ:
[('佐藤次郎', 32, 'リードエンジニア'), ('高橋三郎', 27, 'プログラマー'), ('伊藤四郎', 30, 'プログラマー')]

鈴木花子さんの詳細:
名前: 鈴木花子, 年齢: 29, 役職: 営業担当

解説

  • データの追加
    部門「開発」のリストに対してappend()メソッドを使い、新しい社員情報のタプルを追加しています。
    ※注意:appendメソッドの引数には必ずタプルとしてまとめた1個のオブジェクトを渡してください。
  • データの取り出し
    辞書のキーとリストのインデックスを組み合わせることで、特定部門の任意の社員データを取り出します。
    また、タプルのアンパッキングを用いることで、個々の値(名前、年齢、役職)を変数に展開し、利用しやすくしています。

3.エラー回避と注意点

3.1. 引数の渡し方に注意

 リストのappend()メソッドは、1個の引数しか受け取らないため、以下のようにタプルの丸括弧を省略するとエラーになります。

サンプルプログラム

# NG例: タプルの丸括弧を省略するとエラーとなる
company['開発'].append('伊藤四郎', 30, 'プログラマー')

実行結果

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 2
      1 # NG例: タプルの丸括弧を省略するとエラーとなる
----> 2 company['開発'].append('伊藤四郎', 30, 'プログラマー')

TypeError: list.append() takes exactly one argument (3 given)

解説

  • 上記のコードでは、3つの別々の引数が渡されるため、TypeErrorが発生します。必ず、タプルとして一つにまとめた上で渡す必要があります。

3.2. ネストされたデータへのアクセス方法

 複数のデータ構造がネストしている場合、目的のデータにアクセスするには、キー、インデックス、スライス、アンパッキングなどを組み合わせる必要があります。上記例では、まず部門名(キー)でリストを取得し、次にインデックスでタプルを選び、最後にアンパッキングで個々の値を取り出しています。

まとめ

 ここでは、Pythonにおける階層的なデータ構造の作成方法について、基礎概念の理解から具体例のプログラム解説までを行いました。辞書、リスト、タプルそれぞれの特性を把握し、適材適所に組み合わせることで、現実の複雑な情報も整理しやすくなります。
 今回の例「会社の部門ごとの社員データ管理」を通じ、データの追加・アクセス方法や、エラーを回避するための注意点を学ぶことで、より高度なデータ操作へと応用が可能です。これらの知識を活用し、実際の業務やシステム開発における柔軟で効率的なデータ管理に役立ててください。