0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Python】JSONから指定のエントリを抽出&他のエントリ内のプロパティと一致する場合はそのエントリ内の値も取得する方法

Posted at

概要

JSONファイルから指定のエントリを抽出し、かつ、他のエントリ内の指定のプロパティと一致する場合はそのエントリ内の値も一緒に取得する方法を、備忘録も兼ねて記載します。
(文章だと意図が伝わりづらいので、サンプルコードを...)

サンプルコード解説

以下のようなJSONがあるとします。
サンプルなのでわかりやすいようにしていますが、実際は支店(branch)も製品(product_code)もたくさんある前提です。

001_sample_response.json
{
    "response": {
        "status": "0000",
        "company_code": "12345",
        "branch": {
            "tokyo": [
                {
                    "product_code": "001",
                    "unit_price": "100",
                    "quantity": "10",
                    "sales_amount": "1000",
                    "tokyo_status": "Tokyo、達成です!"
                },
                {
                    "product_code": "002",
                    "unit_price": "200",
                    "quantity": "1",
                    "sales_amount": "200",
                    "tokyo_status": "Tokyo、未達です!"
                }
            ],
            "osaka": [
                {
                    "product_code": "001",
                    "unit_price": "100",
                    "quantity": "2",
                    "sales_amount": "200",
                    "osaka_status": "Osaka、未達です!"
                },
                {
                    "product_code": "002",
                    "unit_price": "200",
                    "quantity": "5",
                    "sales_amount": "1000",
                    "osaka_status": "Osaka、達成です!"
                }
            ]
        }
    }
}

上記から、大阪支店の情報(osakaエントリ全体)を抽出し、かつ、プロパティのproduct_codeunit_priceの両方が一致する東京支社のステータスを取り出すコードを紹介します。今回は001から100まである想定なのでrangeでループを作成しています。

import os
import json

# 出力ディレクトリを作成
output_dir = "./sample_osaka_files"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

for i in range(1, 100):
    json_file_path = f"./sample_json_files/{str(i).zfill(3)}_sample_response.json"
    output_file_path = f"{output_dir}/{str(i).zfill(3)}_osaka.json"

    try:
        with open(json_file_path, "r", encoding="utf-8") as json_file:
            data = json.load(json_file)

        if "response" in data and "branch" in data["response"]:
            branch = data["response"]["branch"]
            if "tokyo" in branch and "osaka" in branch:
                tokyo_branch = branch["tokyo"]
                osaka_branch = branch["osaka"]
                entries_with_status = []
                for osaka in osaka_branch:
                    osaka_factors = (
                        osaka.get("product_code"),
                        osaka.get("unit_price")
                    )
                    for tokyo in tokyo_branch:
                        tokyo_factors = (
                            tokyo.get("product_code"),
                            tokyo.get("unit_price")
                        )
                        if osaka_factors == tokyo_factors:
                            osaka["tokyo_status"] = tokyo.get("tokyo_status")
                            entries_with_status.append(osaka)
                            break

                if entries_with_status:
                    entries_with_status.insert(0, {"branch": "osaka"})
                    with open(output_file_path, "w", encoding="utf-8") as output_file:
                        json.dump(entries_with_status, output_file, ensure_ascii=False, indent=4)

    except (FileNotFoundError, json.JSONDecodeError) as e:
        print(f"処理エラー: {json_file_path} - {e}")

実行結果は以下になります。
例えばproduct_code001unit_price100の製品の場合、大阪支店の情報(quantitysales_amount)を抽出しつつ、同じくproduct_code001unit_price100である東京支店のステータスも取得できます。

001_osaka.json
[
    {
        "branch": "osaka"
    },
    {
        "product_code": "001",
        "unit_price": "100",
        "quantity": "2",
        "sales_amount": "200",
        "osaka_status": "Osaka、未達です!",
        "tokyo_status": "Tokyo、達成です!"
    },
    {
        "product_code": "002",
        "unit_price": "200",
        "quantity": "5",
        "sales_amount": "1000",
        "osaka_status": "Osaka、達成です!",
        "tokyo_status": "Tokyo、未達です!"
    }
]

ネストがかなり深く力技のコーディングですが、これで作業すると100件とか整理する必要がある場合は非常に楽でした。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?