Reputation: 38552
I have a python dictionary where I am iterating it and creating a new dictionary with some calculations. My current code is working fine but I want to know what are the other different ways to do it?
The logic is-
1. if the same `room` has multiple `rate` codes then append it to that room.
2. get the lowest price for every room type.
Existing Code:
datas = [
{"code": "A1KXDY", "room": "A1K", "rate": "XDX", "price": 10},
{"code": "B1KXDY", "room": "B1K", "rate": "XDX", "price": 20},
{"code": "C1KXDY", "room": "C1K", "rate": "XDX", "price": 30},
{"code": "A1KXDY", "room": "A1K", "rate": "XDY", "price": 5},
{"code": "B1KXDY", "room": "B1K", "rate": "XDY", "price": 10},
{"code": "C1KXDY", "room": "C1K", "rate": "XDY", "price": 40},
]
final_result = {}
for data in datas:
display_rate = data["price"]
if data["room"] in final_result:
existing_room = final_result[data["room"]]
existing_room["rate_codes"].append(data["rate"])
current_rate = existing_room["display_rate"]
if current_rate > display_rate:
existing_room["display_rate"] = display_rate
continue
room_data = {"display_rate": display_rate, "rate_codes": [data["rate"]]}
final_result[data["room"]] = room_data
print(final_result)
Expected Output:
{'A1K': {'display_rate': 5, 'rate_codes': ['XDX', 'XDY']}, 'B1K': {'display_rate': 10, 'rate_codes': ['XDX', 'XDY']}, 'C1K': {'display_rate': 30, 'rate_codes': ['XDX', 'XDY']}}
Upvotes: 1
Views: 55
Reputation: 18781
I would say your solution is fine. What constitutes "more smartly" is subjective to a large extent anyway.
I suppose, if you were willing to accept a set
of rate_codes
in the final result instead of a list
, you could get away with fairly few lines of code:
final_result = {}
for data in datas:
room_key = data["room"] # just for readability
final_result.setdefault(room_key, {
"display_rate": data["price"],
"rate_codes": {data["rate"]}
})
final_result[room_key]["display_rate"] = min(
final_result[room_key]["display_rate"],
data["price"]
)
final_result[room_key]["rate_codes"].add(data["rate"])
dict.setdefault
method does nothing to final_result
if it already has the key room_key
; otherwise it inserts it with the value of that new dictionary.min
function instead of explicitly comparing values.set
always has unique values, so we can just call its add
method without needing to check if that rate code already exists.The result:
{'A1K': {'display_rate': 5, 'rate_codes': {'XDX', 'XDY'}}, 'B1K': {'display_rate': 10, 'rate_codes': {'XDX', 'XDY'}}, 'C1K': {'display_rate': 30, 'rate_codes': {'XDX', 'XDY'}}}
Upvotes: 1
Reputation: 1199
You can use pandas for this.
import pandas as pd
datas = [...]
df = pd.DataFrame(datas)
df = df.groupby('room', as_index=False).agg({'price': min, 'rate': list})
df.rename(columns={'price': 'display_rate', 'rate': 'rate_codes'}, inplace=True)
result = df.to_dict('records')
Output:
[{'room': 'A1K', 'display_rate': 5, 'rate_codes': ['XDX', 'XDY']},
{'room': 'B1K', 'display_rate': 10, 'rate_codes': ['XDX', 'XDY']},
{'room': 'C1K', 'display_rate': 30, 'rate_codes': ['XDX', 'XDY']}]
The output can further be treated to match the output you want for final_result.
Upvotes: 2