You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字典排序练习:矮人数据处理任务的替代方案与代码优化咨询

矮人数据处理任务的替代实现与优化方案

一、更简洁的实现方式

直接用(姓名, 帽子颜色)元组作为字典的唯一键,天然解决“姓名+帽子颜色唯一”的规则;用collections.Counter快速统计每种帽子的矮人数量,整个逻辑更紧凑:

from collections import Counter

def process_dwarfs():
    dwarfs = {}
    while True:
        line = input().strip()
        if line == "Once upon a time":
            break
        # 一次拆分完成赋值,避免重复调用split
        name, hat, physics = line.split(" <:> ")
        physics = int(physics)
        # 元组作为键,直接处理力量值替换逻辑
        key = (name, hat)
        if key not in dwarfs or physics > dwarfs[key]:
            dwarfs[key] = physics
    
    # 统计每种帽子对应的矮人总数
    hat_dwarf_count = Counter(hat for name, hat in dwarfs.keys())
    
    # 多条件排序:先按力量降序,再按同帽子矮人数量降序
    sorted_dwarfs = sorted(
        dwarfs.items(),
        key=lambda item: (-item[1], -hat_dwarf_count[item[0][1]])
    )
    
    # 格式化输出
    for (name, hat), physics in sorted_dwarfs:
        print(f"({hat}) {name} <-> {physics}")

process_dwarfs()

二、原有代码的优化点

1. 减少重复的split调用

原代码中对同一行字符串调用了3次split(" <:> "),改成一次拆分后直接赋值,既提升效率又更简洁:

# 原写法
dwarf_name, dwarf_hat_color, dwarf_physics = dwarf_info.split(" <:> ")[0], dwarf_info.split(" <:> ")[1], int(dwarf_info.split(" <:> ")[2])
# 优化后
name, hat, physics = dwarf_info.split(" <:> ")
physics = int(physics)

2. 简化嵌套字典的判断逻辑

用dict.setdefault()替代多层if-else,直接获取对应帽子的子字典,再处理姓名对应的力量值:

def collecting_data():
    dwarfs_dict = {}
    while True:
        dwarf_info = input().strip()
        if dwarf_info == "Once upon a time":
            return dwarfs_dict
        name, hat, physics = dwarf_info.split(" <:> ")
        physics = int(physics)
        # 自动创建不存在的帽子字典,避免多层判断
        hat_dict = dwarfs_dict.setdefault(hat, {})
        # 直接判断并更新最大力量值
        if name not in hat_dict or physics > hat_dict[name]:
            hat_dict[name] = physics

3. 排序逻辑简化

原代码先构建包含number字段的列表,其实可以在排序时动态获取帽子的矮人数量,避免提前存储:

def sorting_dwarfs():
    dict_with_dwarfs = collecting_data()
    # 直接生成待排序的元组列表
    dwarf_list = []
    for hat, name_physics in dict_with_dwarfs.items():
        count = len(name_physics)
        for name, physics in name_physics.items():
            dwarf_list.append( (physics, count, hat, name) )
    # 排序时对前两个值取负实现降序
    for physics, count, hat, name in sorted(dwarf_list, key=lambda x: (-x[0], -x[1])):
        print(f"({hat}) {name} <-> {physics}")

三、sorted函数用法解析与"unhashable dict"错误解决

sorted核心用法

sorted(iterable, key=None, reverse=False)的核心是key参数:它接受一个函数,返回用于排序的依据值。默认按升序排列,要实现降序有两种方式:

  • 对数值类型的依据值取负(比如-physics),适合多条件排序时区分不同字段的排序方向;
  • 设置reverse=True,适合单一条件的降序。

解决"unhashable dict"错误

这个错误的本质是:字典是可变类型,不可被哈希,当你尝试把字典作为字典的键、放进集合,或者在key函数中返回字典时,就会触发这个错误。

你最初尝试排序嵌套字典时出错,大概率是直接把嵌套的子字典(比如dwarfs_dict[hat])作为排序元素,或者用字典作为key的一部分。解决办法是:永远用可哈希类型(元组、字符串、数字等不可变类型)作为排序依据或字典键——比如我们前面用的(name, hat)元组,就是典型的可哈希唯一标识。

多条件排序示例

比如你的需求是“力量降序→同帽子数量降序”,对应的key函数要返回一个元组,元组内元素的优先级从左到右:

# 方式1:对需要降序的数值取负
key=lambda item: (-item[1], -hat_dwarf_count[item[0][1]])
# 方式2:结合reverse,但多条件时不如取负灵活
key=lambda item: (item[1], hat_dwarf_count[item[0][1]]), reverse=True

内容的提问来源于stack exchange,提问作者KNenov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:50:22