简体   繁体   English

Python 嵌套字典迭代并创建新字典

[英]Python nested dictionary iterate and create new dictionary

I have a python dictionary where I am iterating it and creating a new dictionary with some calculations.我有一个 python 字典,我正在迭代它并通过一些计算创建一个新字典。 My current code is working fine but I want to know what are the other ways to do it more smartly.我当前的代码运行良好,但我想知道其他更聪明的方法是什么。

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:预期 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']}}

You can use pandas for this.为此,您可以使用 pandas。

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: 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. output 可以进一步处理以匹配您想要的 final_result 的 output。

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:我想,如果您愿意在最终结果中接受一set rate_codes而不是list ,那么您只需几行代码就可以逃脱:

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"])
  1. Using thedict.setdefault method does nothing to final_result if it already has the key room_key ;如果 dict.setdefault 方法已经拥有密钥room_key ,则使用dict.setdefault方法对final_result没有任何作用; otherwise it inserts it with the value of that new dictionary.否则它会用那个新字典的值插入它。
  2. We can use the min function instead of explicitly comparing values.我们可以使用min function 而不是显式比较值。
  3. And we use the fact that a set always has unique values, so we can just call its add method without needing to check if that rate code already exists.而且我们使用set总是具有唯一值的事实,因此我们可以只调用它的add方法而无需检查该汇率代码是否已经存在。

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'}}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM