4日目のゴール
4日目のテーマは
「辞書型で管理しているユーザーを“探す・絞り込む”ことができるようになること」 です。
1〜3日目で、あなたはすでに CRUD(登録・一覧・更新・削除)を一通り体験しました。
今日はそこに、
ユーザーIDで1人だけ検索する
名前の一部であいまい検索する
検索結果をきれいに表示する
という「R(Read)の応用」を足していきます。
辞書から「1人だけ」を取り出す検索
ユーザーIDでピンポイントに探す
まずは一番シンプルな検索からいきます。
「ユーザーIDを入力して、そのユーザーだけ表示する」機能です。
辞書の構造はこうでした。
users = {
"u001": {"id": "u001", "name": "Taro", "age": 25, "email": "taro@example.com"},
"u002": {"id": "u002", "name": "Hanako", "age": 30, "email": "hanako@example.com"}
}
Pythonこのとき、ID からユーザーを取り出すのはこうでした。
user = users["u001"]
Pythonこれを「アプリの機能」として形にすると、こうなります。
def find_user_by_id(users):
print("=== ユーザー検索(ID指定) ===")
user_id = input("検索したいユーザーID: ").strip()
if user_id not in users:
print("そのIDのユーザーは存在しません。")
return
user = users[user_id]
print("=== 検索結果 ===")
print(f"ID: {user['id']}")
print(f"名前: {user['name']}")
print(f"年齢: {user['age']}")
print(f"メール: {user['email']}")
Pythonここでの重要ポイントは、
「存在チェックをしてから取り出す」 ことです。
user_id not in users を先に確認しておくことで、users[user_id] で KeyError を起こさずに済みます。
「一覧」と「検索」の違いを言葉で整理する
Read には二つの顔がある
ここまでで、Read(読み取り)は二種類出てきました。
全員を表示する「一覧表示」
特定の1人だけを表示する「検索」
どちらも「読む」ですが、
やっていることは少し違います。
一覧表示は、
「全員をぐるっと回して、全員分を表示する」。
検索は、
「条件に合うユーザーだけを取り出して表示する」。
この「条件」という考え方が、
今日のキーワードです。
名前の一部で検索する(あいまい検索)
「部分一致」で探すという発想
現実のアプリでは、
「ID は覚えてないけど、名前に ‘太郎’ が入ってたはず」
みたいな探し方をしたくなります。
そこで、
「名前にキーワードが含まれているユーザーだけを表示する」
という機能を作ります。
def find_users_by_name(users):
print("=== ユーザー検索(名前の一部) ===")
keyword = input("名前に含まれる文字を入力してください: ").strip()
if keyword == "":
print("キーワードが空です。検索を中止します。")
return
keyword_lower = keyword.lower()
found = False
for user_id, user in users.items():
name_lower = user["name"].lower()
if keyword_lower in name_lower:
if not found:
print("=== 検索結果 ===")
found = True
print(f"- ID: {user['id']}")
print(f" 名前: {user['name']}")
print(f" 年齢: {user['age']}")
print(f" メール: {user['email']}")
print("----------")
if not found:
print(f"「{keyword}」を含む名前のユーザーは見つかりませんでした。")
Pythonここで深掘りしたいポイントは、いくつかあります。
users.items() で「ID とユーザー辞書」を同時に取り出しているkeyword_lower in name_lower で「部分一致」を判定している
大文字・小文字の違いを無視するために、両方 lower() にしているfound フラグで「1件もヒットしなかった場合」を判定している
つまり、
「辞書をぐるっと回しながら、条件に合うものだけを拾う」
というパターンを使っています。
検索結果の表示を共通化する
「表示の仕方」を関数にしておくと楽になる
ID 検索でも名前検索でも、
ユーザー情報の表示の仕方はほとんど同じですよね。
こういうときは、
「表示だけを担当する関数」を作っておくとスッキリします。
def print_user(user):
print(f"ID: {user['id']}")
print(f"名前: {user['name']}")
print(f"年齢: {user['age']}")
print(f"メール: {user['email']}")
Pythonこれを使うと、
さっきの ID 検索はこう書き換えられます。
def find_user_by_id(users):
print("=== ユーザー検索(ID指定) ===")
user_id = input("検索したいユーザーID: ").strip()
if user_id not in users:
print("そのIDのユーザーは存在しません。")
return
user = users[user_id]
print("=== 検索結果 ===")
print_user(user)
Python名前検索も、こう書けます。
def find_users_by_name(users):
print("=== ユーザー検索(名前の一部) ===")
keyword = input("名前に含まれる文字を入力してください: ").strip()
if keyword == "":
print("キーワードが空です。検索を中止します。")
return
keyword_lower = keyword.lower()
found = False
for user_id, user in users.items():
name_lower = user["name"].lower()
if keyword_lower in name_lower:
if not found:
print("=== 検索結果 ===")
found = True
print_user(user)
print("----------")
if not found:
print(f"「{keyword}」を含む名前のユーザーは見つかりませんでした。")
Pythonここでの重要ポイントは、
「同じことを何度も書かない」 という意識です。
表示ロジックを1か所にまとめておくと、
あとで表示形式を変えたくなったときも、
その関数だけ直せば済みます。
4日目版メニュー:検索機能を組み込む
3日目までの CRUD に「検索」を足す
これまでの CRUD メニューに、
検索メニューを追加してみます。
def show_menu():
print("==========")
print("ユーザー管理アプリ(4日目)")
print("1: ユーザーを登録する(Create)")
print("2: ユーザー一覧を表示する(Read)")
print("3: ユーザー情報を更新する(Update)")
print("4: ユーザーを削除する(Delete)")
print("5: ユーザーをIDで検索する")
print("6: ユーザーを名前の一部で検索する")
print("0: 終了")
print("==========")
Pythonmain はこうなります。
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 == "0":
print("アプリを終了します。")
break
else:
print("不正な入力です。0〜6 のどれかを選んでください。")
Pythonこれで、
「登録・一覧・更新・削除・検索」
という、かなり実用的なユーザー管理アプリの形になってきます。
4日目の完成コード(要点部分)
検索まわりを中心にした全体像
CRUD 部分は3日目と同じなので、
ここでは「検索」と「表示」の部分を中心に載せます。
def print_user(user):
print(f"ID: {user['id']}")
print(f"名前: {user['name']}")
print(f"年齢: {user['age']}")
print(f"メール: {user['email']}")
def find_user_by_id(users):
print("=== ユーザー検索(ID指定) ===")
user_id = input("検索したいユーザーID: ").strip()
if user_id not in users:
print("そのIDのユーザーは存在しません。")
return
user = users[user_id]
print("=== 検索結果 ===")
print_user(user)
def find_users_by_name(users):
print("=== ユーザー検索(名前の一部) ===")
keyword = input("名前に含まれる文字を入力してください: ").strip()
if keyword == "":
print("キーワードが空です。検索を中止します。")
return
keyword_lower = keyword.lower()
found = False
for user_id, user in users.items():
name_lower = user["name"].lower()
if keyword_lower in name_lower:
if not found:
print("=== 検索結果 ===")
found = True
print_user(user)
print("----------")
if not found:
print(f"「{keyword}」を含む名前のユーザーは見つかりませんでした。")
Pythonこの3つの関数だけでも、
「辞書を使った検索の基本パターン」がぎゅっと詰まっています。
「検索」を自分の言葉で説明してみる
ここまで来たあなたなら、こう言えるはず
ID 検索
「ユーザーIDを入力してもらい、そのIDが users 辞書にあれば、そのユーザーだけを表示する。」
名前検索
「users 辞書をぐるっと回しながら、名前にキーワードを含むユーザーだけを拾って表示する。
大文字・小文字の違いは無視する。」
print_user
「1人のユーザー辞書を、決まったフォーマットで表示する。」
ここまで自分の言葉で説明できれば、
「辞書型+条件+ループで“探す”」 という感覚は、もうあなたのものです。
4日目のまとめ:今日つかんでほしい感覚
今日の本質は、これです。
Read(読み取り)は「全部表示」だけではなく、「条件に合うものだけ表示」も含んでいる。
辞書の検索は、「キーで一発」と「値の中身を見ながら絞り込む」の二種類がある。in と lower() を組み合わせると、あいまい検索(部分一致・大文字小文字無視)が簡単に書ける。
表示ロジックを関数にまとめると、コードが読みやすくなり、変更にも強くなる。
ここまで来たあなたなら、
5日目以降の「並び替え(ソート)」「条件を組み合わせた絞り込み」「ファイル保存」といった
“アプリとしての完成度を上げるステップ”にも、自然に進んでいけます。


