使用词典理解和 If/Else 条件从 API 响应中选择 key/value 对
Selecting key/value pairs from API Response using Dictionary Comprehension with If/Else conditions
我已经编制了一份名为“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": "spengler@ghostbusters.example.com",
"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": "glenda@south.oz.coven"
},
"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。
为此,我尝试在字典理解中使用三元表达式来处理 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-loops 简化为推导式的一个好方法是首先使用常规 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-loop。但是,您的问题是如何使用理解来解决它,所以这是我的版本:
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"]]
两者的最大区别在于第一个很容易调试,或者至少遵循逻辑。虽然第二个很难真正跟上。
两者的结果:
[{'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'}]
我已经编制了一份名为“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": "spengler@ghostbusters.example.com",
"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": "glenda@south.oz.coven"
},
"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。
为此,我尝试在字典理解中使用三元表达式来处理 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-loops 简化为推导式的一个好方法是首先使用常规 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-loop。但是,您的问题是如何使用理解来解决它,所以这是我的版本:
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"]]
两者的最大区别在于第一个很容易调试,或者至少遵循逻辑。虽然第二个很难真正跟上。
两者的结果:
[{'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'}]