Python | 1 日 120 分 × 7 日アプリ学習:辞書型で作るユーザー管理アプリ(中級編)

Web APP Python
スポンサーリンク

5日目のゴール

5日目のテーマは
「辞書で管理しているユーザーを“並び替えて表示できるようになること” です。

ここまでであなたは、辞書型を使って

ユーザーを登録する(Create)
ユーザー一覧を表示する(Read)
ユーザー情報を更新する(Update)
ユーザーを削除する(Delete)
ID や名前で検索する

というところまで来ています。

5日目ではここに

名前順に並べて表示する
年齢順に並べて表示する
ID 順に並べて表示する

という「並び替え(ソート)」の感覚を足していきます。


辞書は「順番を持たない」という前提

users は「順番が保証されない集まり」

まず、ここをはっきりさせておきます。

ユーザー一覧は、こんな辞書でした。

users = {
    "u001": {"id": "u001", "name": "Taro", "age": 25, "email": "taro@example.com"},
    "u002": {"id": "u002", "name": "Hanako", "age": 30, "email": "hanako@example.com"},
    "u003": {"id": "u003", "name": "Jiro", "age": 20, "email": "jiro@example.com"}
}
Python

この users は「ユーザーID → ユーザー辞書」の対応を持っていますが、
「どの順番で取り出されるか」は本質的には保証されません。

Python 3.7 以降では「追加した順」が保持されますが、
ユーザー管理アプリとしては

「名前順で見たい」
「年齢の若い順で見たい」

といった「意味のある順番」で表示したくなります。

そこで必要になるのが、
「辞書から一度リストを作って、それを並び替える」
という発想です。


sorted と key で「並び替えの基準」を決める

sorted は「並び替えた新しいリストを返す」

Python には sorted という関数があります。

numbers = [5, 2, 9, 1]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 2, 5, 9]
Python

これは「元のリストを壊さずに、並び替えた新しいリストを返す」関数です。

ユーザー管理アプリでは、
「ユーザーのリスト」を作って、それを sorted で並び替えます。


users から「ユーザーのリスト」を作る

users.values() を使って「値だけ」を取り出す

users は「ID → ユーザー辞書」の辞書です。
ここから「ユーザー辞書だけのリスト」を作るには、values() を使います。

user_list = list(users.values())
Python

これで、user_list はこんなイメージになります。

[
    {"id": "u001", "name": "Taro", "age": 25, "email": "taro@example.com"},
    {"id": "u002", "name": "Hanako", "age": 30, "email": "hanako@example.com"},
    {"id": "u003", "name": "Jiro", "age": 20, "email": "jiro@example.com"}
]
Python

この「ユーザー辞書のリスト」に対して、
sorted を使って並び替えていきます。


名前順に並べて表示する

key に「並び替えの基準」を教える

sorted は、key という引数で
「何を基準に並び替えるか」を指定できます。

ユーザーを名前順に並べたいなら、
「ユーザー辞書の "name" を基準にする」と教えればいいわけです。

def show_users_sorted_by_name(users):
    print("=== ユーザー一覧(名前順) ===")

    if not users:
        print("ユーザーはまだ登録されていません。")
        return

    user_list = list(users.values())

    sorted_users = sorted(user_list, key=lambda u: u["name"])

    for user in sorted_users:
        print(f"ID: {user['id']}")
        print(f"名前: {user['name']}")
        print(f"年齢: {user['age']}")
        print(f"メール: {user['email']}")
        print("----------")
Python

ここで深掘りしたいポイントは、いくつかあります。

list(users.values()) で「ユーザー辞書のリスト」を作っていること。
sorted(..., key=lambda u: u["name"]) で「name を基準に並び替える」と指定していること。
lambda u: u["name"] は「ユーザー辞書 u から、並び替えに使う値(ここでは name)を取り出す小さな関数」です。

つまり、

「辞書の集まりを、特定のキーの値で並び替える」
というパターンを手に入れたことになります。


年齢順に並べて表示する

数値でも同じように key を使う

今度は「年齢の若い順」に並べてみます。

やることは名前のときと同じで、
基準を "age" に変えるだけです。

def show_users_sorted_by_age(users):
    print("=== ユーザー一覧(年齢順) ===")

    if not users:
        print("ユーザーはまだ登録されていません。")
        return

    user_list = list(users.values())

    sorted_users = sorted(user_list, key=lambda u: u["age"])

    for user in sorted_users:
        print(f"ID: {user['id']}")
        print(f"名前: {user['name']}")
        print(f"年齢: {user['age']}")
        print(f"メール: {user['email']}")
        print("----------")
Python

ここでのポイントは、

"name" だろうが "age" だろうが、
「並び替えたい基準のキーを key に指定するだけ」

というシンプルさです。


降順(大きい順)に並べたいとき

reverse=True を使う

「年齢の高い順」に並べたいときは、
sortedreverse=True を渡します。

sorted_users = sorted(user_list, key=lambda u: u["age"], reverse=True)
Python

これで、「age の大きい順」に並びます。

同じように、
「名前を Z→A の逆順にしたい」ときも、
reverse=True をつけるだけです。


ID 順に並べて表示する

キーそのものを基準にするパターン

ID 順で並べたいときは、
users.values() ではなく users.items() を使う方法もあります。

def show_users_sorted_by_id(users):
    print("=== ユーザー一覧(ID順) ===")

    if not users:
        print("ユーザーはまだ登録されていません。")
        return

    items = list(users.items())

    sorted_items = sorted(items, key=lambda pair: pair[0])

    for user_id, user in sorted_items:
        print(f"ID: {user_id}")
        print(f"名前: {user['name']}")
        print(f"年齢: {user['age']}")
        print(f"メール: {user['email']}")
        print("----------")
Python

ここでの重要ポイントは、

users.items()(キー, 値) のペアを返すこと。
lambda pair: pair[0] で「ペアの0番目=キー(ID)」を基準にしていること。

つまり、

「キーで並び替えたいときは items() を使う」
というパターンです。


表示ロジックを共通化して、重複を減らす

print_user と「ユーザーのリストを表示する関数」

並び替えの関数が増えてくると、
「表示部分がほぼ同じコードだらけ」になりがちです。

そこで、表示を共通化します。

def print_user(user):
    print(f"ID: {user['id']}")
    print(f"名前: {user['name']}")
    print(f"年齢: {user['age']}")
    print(f"メール: {user['email']}")
Python

さらに、「ユーザーのリストを表示する」関数も作れます。

def print_user_list(user_list, title):
    print(f"=== {title} ===")

    if not user_list:
        print("ユーザーはまだ登録されていません。")
        return

    for user in user_list:
        print_user(user)
        print("----------")
Python

これを使うと、
名前順の関数はこう書き換えられます。

def show_users_sorted_by_name(users):
    user_list = list(users.values())
    sorted_users = sorted(user_list, key=lambda u: u["name"])
    print_user_list(sorted_users, "ユーザー一覧(名前順)")
Python

年齢順も同じです。

def show_users_sorted_by_age(users):
    user_list = list(users.values())
    sorted_users = sorted(user_list, key=lambda u: u["age"])
    print_user_list(sorted_users, "ユーザー一覧(年齢順)")
Python

ここでの大事な感覚は、

「並び替え」と「表示」を分けて考える
並び替えは sorted の仕事
表示は print_user_list の仕事

という役割分担です。


5日目版メニュー:並び替え機能を組み込む

CRUD+検索+ソートで、かなり“アプリらしく”なる

これまでのメニューに、
並び替え表示を追加してみます。

def show_menu():
    print("==========")
    print("ユーザー管理アプリ(5日目)")
    print("1: ユーザーを登録する(Create)")
    print("2: ユーザー一覧を表示する(登録順)")
    print("3: ユーザー情報を更新する(Update)")
    print("4: ユーザーを削除する(Delete)")
    print("5: ユーザーをIDで検索する")
    print("6: ユーザーを名前の一部で検索する")
    print("7: ユーザー一覧(名前順)")
    print("8: ユーザー一覧(年齢順)")
    print("0: 終了")
    print("==========")
Python

main はこうなります。

def main():
    users = {}

    while True:
        show_menu()
        choice = input("番号を選んでください: ").strip()

        if choice == "1":
            add_user(users)
        elif choice == "2":
            show_all_users(users)
        elif choice == "3":
            update_user(users)
        elif choice == "4":
            delete_user(users)
        elif choice == "5":
            find_user_by_id(users)
        elif choice == "6":
            find_users_by_name(users)
        elif choice == "7":
            show_users_sorted_by_name(users)
        elif choice == "8":
            show_users_sorted_by_age(users)
        elif choice == "0":
            print("アプリを終了します。")
            break
        else:
            print("不正な入力です。0〜8 のどれかを選んでください。")
Python

これで、

登録
一覧(登録順)
更新
削除
検索(ID・名前)
並び替え表示(名前順・年齢順)

という、かなり実用的なユーザー管理アプリになってきます。


「どこを変えれば何が変わるか」を意識する

並び替えの基準を変えるのは、key の部分だけ

ここまで来たあなたなら、
こういうことが自分でできるはずです。

名字だけで並び替えたい
lambda u: u["name"].split()[0] のように、key の中で加工する。

年齢が同じときは名前順にしたい
key=lambda u: (u["age"], u["name"]) のように、タプルを返す。

降順にしたい
reverse=True をつける。

つまり、

「並び替えのルールは、key に渡す関数で自由に設計できる」

ということです。


5日目のまとめ:今日つかんでほしい感覚

今日の本質は、これです。

辞書そのものには「順番」という概念はない。
並び替えたいときは、一度「値のリスト」を作ってから sorted を使う。
sorted(..., key=...) で「何を基準に並び替えるか」を指定できる。
名前順・年齢順・ID順など、基準を変えるだけでいろんな並び替えができる。
「並び替え」と「表示」を関数で分けると、コードがきれいになり、変更にも強くなる。

ここまで来ているあなたなら、
6日目・7日目で「ファイルへの保存・読み込み」や
「アプリ起動時に前回のデータを復元する」といった
“本当に使えるユーザー管理アプリ”に仕上げていけます。

タイトルとURLをコピーしました