如何使用Python列表推导式生成包含多子键的嵌套字典
Hey there! Great question—you’re right that dictionary comprehensions (you mentioned list comprehensions, but we’re building dictionaries here) are clean, and avoiding repeated iterations over the same list is a smart call for efficiency, especially with larger datasets.
Let’s break down your options:
Option 1: Clean Nested Dictionary Comprehensions (Multiple Iterations)
If your roomStayInfos list is small and performance isn’t a critical concern, this is the most concise way to build your nested dictionary. It uses three separate dictionary comprehensions to populate each sub-dictionary:
import json jsn = """{ "availResponse": { "roomStayInfos": [ { "rateCodeID": 400166, "amount": 9000, "depositAmount": 0, "baseAmt": 9000 }, { "rateCodeID": 402451, "amount": 96000, "depositAmount": 0, "baseAmt": 96000 }, { "rateCodeID": 400164, "amount": 9000, "depositAmount": 0, "baseAmt": 9000 }, { "rateCodeID": 402598, "amount": 5100, "depositAmount": 0, "baseAmt": 9000 } ] } }""" availability = json.loads(jsn, strict=False) room_stays = availability["availResponse"]["roomStayInfos"] result = { "depositAmounts": {str(rs["rateCodeID"]): rs["depositAmount"] for rs in room_stays}, "amount": {str(rs["rateCodeID"]): rs["amount"] for rs in room_stays}, "baseAmt": {str(rs["rateCodeID"]): rs["baseAmt"] for rs in room_stays} } print(json.dumps(result, indent=2))
This will output exactly what you want, but it does iterate over the list three times.
Option 2: Single Iteration (Efficient, Readable)
If you want to iterate only once (the main goal you mentioned), your original for-loop approach is already excellent. We can make it a bit cleaner using collections.defaultdict to avoid manually initializing empty sub-dictionaries:
import json from collections import defaultdict jsn = """{ "availResponse": { "roomStayInfos": [ { "rateCodeID": 400166, "amount": 9000, "depositAmount": 0, "baseAmt": 9000 }, { "rateCodeID": 402451, "amount": 96000, "depositAmount": 0, "baseAmt": 96000 }, { "rateCodeID": 400164, "amount": 9000, "depositAmount": 0, "baseAmt": 9000 }, { "rateCodeID": 402598, "amount": 5100, "depositAmount": 0, "baseAmt": 9000 } ] } }""" availability = json.loads(jsn, strict=False) result = defaultdict(dict) for rs in availability["availResponse"]["roomStayInfos"]: rc_id = str(rs["rateCodeID"]) result["depositAmounts"][rc_id] = rs["depositAmount"] result["amount"][rc_id] = rs["amount"] result["baseAmt"][rc_id] = rs["baseAmt"] # Convert defaultdict to regular dict if needed result = dict(result) print(json.dumps(result, indent=2))
This iterates over the list once, updates all three sub-dictionaries in one go, and keeps the code readable.
Can We Do This with a Single Comprehension?
Short answer: Not really in a way that’s more readable or efficient than the loop. Dictionary comprehensions are designed to generate a single dictionary at a time. To build multiple sub-dictionaries in one comprehension, you’d have to use a workaround (like generating an intermediate structure and then splitting it), which ends up being less clear and may still involve multiple iterations.
For example, here’s a workaround that uses a single comprehension to build an intermediate map, then splits it into your target structure—but it still iterates twice (once for the intermediate map, once for each sub-dictionary):
room_stays = availability["availResponse"]["roomStayInfos"] intermediate = {str(rs["rateCodeID"]): { "deposit": rs["depositAmount"], "amount": rs["amount"], "base": rs["baseAmt"] } for rs in room_stays} result = { "depositAmounts": {k: v["deposit"] for k, v in intermediate.items()}, "amount": {k: v["amount"] for k, v in intermediate.items()}, "baseAmt": {k: v["base"] for k, v in intermediate.items()} }
This works, but it’s not better than your original loop for clarity or efficiency.
Final Recommendation
Stick with your original loop (or the defaultdict version) for single-iteration efficiency and readability. The nested comprehension approach is great for small lists where you prioritize brevity over minimal iterations.
Expected Output
{ "depositAmounts": { "400166": 0, "402451": 0, "400164": 0, "402598": 0 }, "amount": { "400166": 9000, "402451": 96000, "400164": 9000, "402598": 5100 }, "baseAmt": { "400166": 9000, "402451": 96000, "400164": 9000, "402598": 9000 } }
内容的提问来源于stack exchange,提问作者A l w a y s S u n n y




