Python - If/Else条件付きの辞書内包表記を使用してAPIレスポンスからキー/値のペアを選択する

okwaves2024-01-25  7

「user_responses」という API 応答のリストを作成しました。これはリスト内の応答の例です。

{
    "ok": true,
    "members": [
        {
            "id": "W012A3CDE",
            "team_id": "T012AB3C4",
            "name": "spengler",
            "deleted": false,
            "color": "9f69e7",
            "real_name": "spengler",
            "tz": "America/Los_Angeles",
            "tz_label": "Pacific Daylight Time",
            "tz_offset": -25200,
            "profile": {
                "avatar_hash": "ge3b51ca72de",
                "status_text": "Print is dead",
                "status_emoji": ":books:",
                "real_name": "Egon Spengler",
                "display_name": "spengler",
                "real_name_normalized": "Egon Spengler",
                "display_name_normalized": "spengler",
                "email": "[email protected]",
                "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
                "team": "T012AB3C4"
            },
            "is_admin": true,
            "is_owner": false,
            "is_primary_owner": false,
            "is_restricted": false,
            "is_ultra_restricted": false,
            "is_bot": false,
            "updated": 1502138686,
            "is_app_user": false,
            "has_2fa": false
        },
        {
            "id": "W07QCRPA4",
            "team_id": "T0G9PQBBK",
            "name": "glinda",
            "deleted": false,
            "color": "9f69e7",
            "real_name": "Glinda Southgood",
            "tz": "America/Los_Angeles",
            "tz_label": "Pacific Daylight Time",
            "tz_offset": -25200,
            "profile": {
                "avatar_hash": "8fbdd10b41c6",
                "image_24": "https://a.slack-edge.com...png",
                "image_32": "https://a.slack-edge.com...png",
                "image_48": "https://a.slack-edge.com...png",
                "image_72": "https://a.slack-edge.com...png",
                "image_192": "https://a.slack-edge.com...png",
                "image_512": "https://a.slack-edge.com...png",
                "image_1024": "https://a.slack-edge.com...png",
                "image_original": "https://a.slack-edge.com...png",
                "first_name": "Glinda",
                "last_name": "Southgood",
                "title": "Glinda the Good",
                "phone": "",
                "skype": "",
                "real_name": "Glinda Southgood",
                "real_name_normalized": "Glinda Southgood",
                "display_name": "Glinda the Fairly Good",
                "display_name_normalized": "Glinda the Fairly Good",
                "email": "[email protected]"
            },
            "is_admin": true,
            "is_owner": false,
            "is_primary_owner": false,
            "is_restricted": false,
            "is_ultra_restricted": false,
            "is_bot": false,
            "updated": 1480527098,
            "has_2fa": false
        }
    ],
    "cache_ts": 1498777272,
    "response_metadata": {
        "next_cursor": "dXNlcjpVMEc5V0ZYTlo="
    }
}

次のもので構成される辞書を構築したいと考えています。

1.ユーザーの real_name であるキー。ユーザーの real_name がない場合は、ユーザーの display_name を使用したいと思います。

このため、辞書内包表記で 3 項式を使用して if/else 条件を処理しようとしました。

{(sub_dict['profile']['real_name'] if 'real_name' in sub_dict['profile] 
  else sub_dict['profile']['display_name']):value
  for response in user_responses
  for sub_dict in response.get('members')}

これはデフォルトで各ユーザーの display_name を使用するようですが、これは私が望むものではありません。

2.各ユーザーのすべての画像のリストである値。

このために、「image」という単語で始まるすべてのキーの値を含むリスト内包表記を作成できると考えました。

{(key:[sub_dict['profile'][k] for k in sub_dict['profile'] if k.startswith('image')]
  for response in user_responses
  for sub_dict in response.get('members')}

ありますかこれを達成する方法はありますか?何かございましたら、よろしくお願いいたします。



------------------------

for ループを内包表記に減らす良い方法は、まず通常の for ループを使用してプロセスを視覚化することです。

newLst = []
for member in var["members"]:
    d = {"images": []}
    for k, v in member["profile"].items():
        if k.startswith("image"):
            d["images"].append(v)

    d["name"] = member["profile"].get("real_name")
    if not d["name"]:
        member["profile"].get("display_name")
    newLst.append(d)

個人的には、上記の for ループを使用します。ただし、あなたの質問は、内包表記を使用してどのように解決するかということでした。そのため、これに対する私のバージョンは次のとおりです。

newLst = [{"images": [v for k, v in member["profile"].items() if k.startswith("image")],
            "name": member["profile"].get("real_name", member["profile"].get("display_name"))} for member in var["members"]]

両方の大きな違いは、最初のものはデバッグするのが非常に簡単であるか、少なくともロジックに従うのが簡単であることです。一方、2 番目の方法は実際に理解するのがかなり難しいです。

両方の結果:

[{'images': ['https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg',
             'https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg',
             'https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg',
             'https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg',
             'https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg',
             'https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg'],
  'name': 'Egon Spengler'},
 {'images': ['https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png',
             'https://a.slack-edge.com...png'],
  'name': 'Glinda Southgood'}]

1

@Hampus_Larsson 説明ありがとうございます。私も、通常の for ループの方が読みやすく、デバッグが簡単であることに同意します。

– ジェームズ D.

2020 年 9 月 4 日 21:01

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。