【Python】部分一致で辞書から検索する方法

Pythonで辞書から特定の情報を探すとき、部分一致検索はとても便利です。

この記事では、forループやリスト内包表記、正規表現を使って辞書のキーや値を部分一致で検索する方法をわかりやすく解説します。

また、複数条件での検索やネストされた辞書の検索、大文字・小文字を無視した検索など、応用的なテクニックも紹介します。

目次から探す

部分一致検索の基本的な方法

Pythonで辞書から部分一致検索を行う方法はいくつかあります。

ここでは、基本的な方法としてforループとリスト内包表記を使った部分一致検索について解説します。

forループを使った部分一致検索

forループを使って辞書のキーや値に対して部分一致検索を行う方法を見ていきましょう。

キーに対する部分一致検索

まず、辞書のキーに対して部分一致検索を行う方法です。

以下の例では、キーに特定の文字列が含まれているかどうかをチェックしています。

# 辞書の定義
sample_dict = {
    'apple': 1,
    'banana': 2,
    'grape': 3,
    'apricot': 4
}
# 部分一致検索の対象となる文字列
search_key = 'ap'
# 部分一致検索
matching_keys = []
for key in sample_dict.keys():
    if search_key in key:
        matching_keys.append(key)
print(matching_keys)  # 出力: ['apple', 'apricot']

このコードでは、search_keyがキーに含まれているかどうかをチェックし、一致するキーをリストに追加しています。

値に対する部分一致検索

次に、辞書の値に対して部分一致検索を行う方法です。

以下の例では、値が特定の文字列を含んでいるかどうかをチェックしています。

# 辞書の定義
sample_dict = {
    'apple': 'fruit',
    'banana': 'fruit',
    'carrot': 'vegetable',
    'grape': 'fruit'
}
# 部分一致検索の対象となる文字列
search_value = 'fruit'
# 部分一致検索
matching_items = []
for key, value in sample_dict.items():
    if search_value in value:
        matching_items.append((key, value))
print(matching_items)  # 出力: [('apple', 'fruit'), ('banana', 'fruit'), ('grape', 'fruit')]

このコードでは、search_valueが値に含まれているかどうかをチェックし、一致するキーと値のペアをリストに追加しています。

リスト内包表記を使った部分一致検索

リスト内包表記を使うと、より簡潔に部分一致検索を行うことができます。

キーに対する部分一致検索

リスト内包表記を使って、辞書のキーに対する部分一致検索を行う方法です。

# 辞書の定義
sample_dict = {
    'apple': 1,
    'banana': 2,
    'grape': 3,
    'apricot': 4
}
# 部分一致検索の対象となる文字列
search_key = 'ap'
# 部分一致検索
matching_keys = [key for key in sample_dict.keys() if search_key in key]
print(matching_keys)  # 出力: ['apple', 'apricot']

リスト内包表記を使うことで、forループを使った場合と同じ結果をより簡潔に得ることができます。

値に対する部分一致検索

リスト内包表記を使って、辞書の値に対する部分一致検索を行う方法です。

# 辞書の定義
sample_dict = {
    'apple': 'fruit',
    'banana': 'fruit',
    'carrot': 'vegetable',
    'grape': 'fruit'
}
# 部分一致検索の対象となる文字列
search_value = 'fruit'
# 部分一致検索
matching_items = [(key, value) for key, value in sample_dict.items() if search_value in value]
print(matching_items)  # 出力: [('apple', 'fruit'), ('banana', 'fruit'), ('grape', 'fruit')]

リスト内包表記を使うことで、forループを使った場合と同じ結果をより簡潔に得ることができます。

以上が、forループとリスト内包表記を使った部分一致検索の基本的な方法です。

次のセクションでは、正規表現を使った部分一致検索について解説します。

正規表現を使った部分一致検索

部分一致検索を行う際に、正規表現を使うと非常に強力な検索が可能になります。

正規表現を使うことで、単純な部分一致だけでなく、より複雑なパターンマッチングも行うことができます。

正規表現の基本

正規表現(Regular Expression、略してregexまたはregexp)は、文字列のパターンを表現するための特殊な文字列です。

例えば、以下のようなパターンがあります:

メタキャラクター意味
.任意の1文字
*直前の文字が0回以上繰り返される
+直前の文字が1回以上繰り返される
?直前の文字が0回または1回現れる
[]括弧内のいずれかの文字
^文字列の先頭
$文字列の末尾

reモジュールの使い方

Pythonでは、正規表現を扱うためにreモジュールを使用します。

reモジュールには、正規表現を使った検索や置換を行うための関数が多数用意されています。

以下に代表的な関数を紹介します:

メソッド説明
re.search(pattern, string)文字列全体を検索し、最初にマッチした部分を返す
re.match(pattern, string)文字列の先頭がパターンにマッチするかをチェックする
re.findall(pattern, string)文字列全体を検索し、マッチしたすべての部分をリストで返す
re.sub(pattern, repl, string)パターンにマッチした部分を置換する

正規表現を使った辞書の部分一致検索

正規表現を使って辞書のキーや値を部分一致検索する方法を見ていきましょう。

キーに対する正規表現検索

まずは、辞書のキーに対して正規表現を使った部分一致検索を行う方法を紹介します。

以下の例では、キーに特定のパターンが含まれるかどうかをチェックします。

import re
# サンプル辞書
sample_dict = {
    "apple": 1,
    "banana": 2,
    "cherry": 3,
    "date": 4,
    "elderberry": 5
}
# 正規表現パターン
pattern = r'a.*e'
# キーに対する正規表現検索
matched_keys = {k: v for k, v in sample_dict.items() if re.search(pattern, k)}
print(matched_keys)

このコードでは、キーに対して正規表現パターンr'a.*e'を適用し、マッチするキーとその値を新しい辞書として返しています。

実行結果は以下のようになります:

{'apple': 1, 'date': 4}

値に対する正規表現検索

次に、辞書の値に対して正規表現を使った部分一致検索を行う方法を紹介します。

以下の例では、値が文字列である場合に特定のパターンが含まれるかどうかをチェックします。

import re
# サンプル辞書
sample_dict = {
    "item1": "apple pie",
    "item2": "banana split",
    "item3": "cherry tart",
    "item4": "date cake",
    "item5": "elderberry jam"
}
# 正規表現パターン
pattern = r'.*pie'
# 値に対する正規表現検索
matched_values = {k: v for k, v in sample_dict.items() if re.search(pattern, v)}
print(matched_values)

このコードでは、値に対して正規表現パターンr'.*pie'を適用し、マッチする値とそのキーを新しい辞書として返しています。

実行結果は以下のようになります:

{'item1': 'apple pie'}

このように、正規表現を使うことで、より柔軟で強力な部分一致検索が可能になります。

正規表現のパターンを工夫することで、さまざまな検索条件に対応することができます。

辞書の部分一致検索の応用

部分一致検索の基本を理解したところで、さらに応用的な検索方法について見ていきましょう。

ここでは、複数条件での部分一致検索、ネスト構造に対する部分一致検索、大文字・小文字を無視した部分一致検索について解説します。

複数条件での部分一致検索

複数の条件を組み合わせて部分一致検索を行うことができます。

例えば、キーと値の両方に対して条件を設定する場合や、複数の値に対して条件を設定する場合などです。

サンプルコード

以下の例では、キーに name を含み、値に John を含むエントリを検索します。

data = {
    "name1": "John Doe",
    "name2": "Jane Smith",
    "username": "johnny123",
    "email": "[email protected]"
}
# キーに `name` を含み、値に `John` を含むエントリを検索
result = {k: v for k, v in data.items() if "name" in k and "John" in v}
print(result)

実行結果

{'name1': 'John Doe'}

辞書のネスト構造に対する部分一致検索

辞書がネスト構造になっている場合でも部分一致検索を行うことができます。

ネストされた辞書の中身を再帰的に検索する方法を見てみましょう。

サンプルコード

以下の例では、ネストされた辞書の中からキーに name を含むエントリを検索します。

data = {
    "user1": {
        "name": "John Doe",
        "email": "[email protected]"
    },
    "user2": {
        "name": "Jane Smith",
        "email": "[email protected]"
    },
    "admin": {
        "username": "admin",
        "email": "[email protected]"
    }
}
def search_nested_dict(d, key_substr):
    result = {}
    for k, v in d.items():
        if isinstance(v, dict):
            nested_result = search_nested_dict(v, key_substr)
            if nested_result:
                result[k] = nested_result
        elif key_substr in k:
            result[k] = v
    return result
# キーに `name` を含むエントリを検索
result = search_nested_dict(data, "name")
print(result)

実行結果

{'user1': {'name': 'John Doe'}, 'user2': {'name': 'Jane Smith'}}

大文字・小文字を無視した部分一致検索

大文字・小文字を無視して部分一致検索を行う場合、キーや値をすべて小文字または大文字に変換してから検索を行います。

サンプルコード

以下の例では、キーに NAME を含むエントリを大文字・小文字を無視して検索します。

data = {
    "Name1": "John Doe",
    "name2": "Jane Smith",
    "Username": "johnny123",
    "Email": "[email protected]"
}
# キーに `NAME` を含むエントリを大文字・小文字を無視して検索
result = {k: v for k, v in data.items() if "name" in k.lower()}
print(result)

実行結果

{'Name1': 'John Doe', 'name2': 'Jane Smith'}

以上が、辞書の部分一致検索の応用方法です。

これらのテクニックを活用することで、より柔軟で効率的なデータ検索が可能になります。

実践例

ここでは、部分一致検索を実際のシナリオでどのように活用できるかを具体的な例を通じて解説します。

部分一致検索はデータフィルタリングやログ解析など、さまざまな場面で役立ちます。

部分一致検索を使ったデータフィルタリング

データフィルタリングは、特定の条件に一致するデータを抽出する作業です。

例えば、顧客データベースから特定の名前や住所を含むレコードを抽出する場合に部分一致検索が役立ちます。

以下は、顧客データベースから「東京」を含む住所を持つ顧客を抽出する例です。

# 顧客データベース(辞書形式)
customers = {
    1: {"name": "山田太郎", "address": "東京都新宿区"},
    2: {"name": "鈴木一郎", "address": "大阪府大阪市"},
    3: {"name": "佐藤花子", "address": "東京都渋谷区"},
    4: {"name": "田中次郎", "address": "神奈川県横浜市"}
}
# 部分一致検索を使って「東京」を含む住所を持つ顧客を抽出
tokyo_customers = {k: v for k, v in customers.items() if "東京" in v["address"]}
# 結果を表示
print(tokyo_customers)
{1: {'name': '山田太郎', 'address': '東京都新宿区'}, 3: {'name': '佐藤花子', 'address': '東京都渋谷区'}}

この例では、リスト内包表記を使って「東京」を含む住所を持つ顧客を抽出しています。

結果として、山田太郎さんと佐藤花子さんのデータが抽出されました。

部分一致検索を使ったログ解析

ログ解析は、システムやアプリケーションのログファイルを解析して特定のイベントやエラーを検出する作業です。

部分一致検索を使うことで、特定のキーワードを含むログエントリを効率的に抽出できます。

以下は、ログファイルから ERROR を含むエントリを抽出する例です。

# ログデータ(辞書形式)
logs = {
    1: "INFO: サーバーが起動しました。",
    2: "ERROR: データベース接続に失敗しました。",
    3: "INFO: ユーザーがログインしました。",
    4: "ERROR: ファイルが見つかりません。",
    5: "WARNING: メモリ使用量が高いです。"
}
# 部分一致検索を使って `ERROR` を含むログエントリを抽出
error_logs = {k: v for k, v in logs.items() if "ERROR" in v}
# 結果を表示
print(error_logs)
{2: 'ERROR: データベース接続に失敗しました。', 4: 'ERROR: ファイルが見つかりません。'}

この例では、リスト内包表記を使って ERROR を含むログエントリを抽出しています。

結果として、データベース接続エラーとファイルが見つからないエラーのログエントリが抽出されました。

これらの実践例を通じて、部分一致検索がどのようにデータフィルタリングやログ解析に役立つかを理解していただけたと思います。

部分一致検索は、特定の条件に一致するデータを効率的に抽出するための強力なツールです。

目次から探す