【问题标题】:How to print a nested defaultdict without including the class/type?如何在不包含类/类型的情况下打印嵌套的 defaultdict?
【发布时间】:2021-11-28 01:19:27
【问题描述】:

我有以下代码:

from collections import defaultdict
db1 = {'Adam': {'Cleaning': 4, 'Tutoring': 2, 'Baking': 1},
        'Betty': {'Gardening': 2, 'Tutoring': 1, 'Cleaning': 3},
        'Charles': {'Plumbing': 2, 'Cleaning': 5},
        'Diane': {'Laundry': 2, 'Cleaning': 4, 'Gardening': 3}}

def by_skill(db1 : {str:{str:int}}) -> [int,[str,[str]]]:
    order_skills = defaultdict(lambda:defaultdict(list))
    for k,v in db1.items():
        for key,value in v.items():
            order_skills[value][key].append(k)

    dict(order_skills)
    order_skills_sorted = sorted( sorted(order_skills.items()), reverse=True )
    return order_skills_sorted


if __name__ == '__main__':
    print(by_skill(db1))

输出:

[(5, defaultdict(<class 'list'>, {'Cleaning': ['Charles']})), (4, defaultdict(<class 'list'>, {'Cleaning': ['Adam', 'Diane']})), (3, defaultdict(<class 'list'>, {'Cleaning': ['Betty'], 'Gardening': ['Diane']})), (2, defaultdict(<class 'list'>, {'Tutoring': ['Adam'], 'Gardening': ['Betty'], 'Plumbing': ['Charles'], 'Laundry': ['Diane']})), (1, defaultdict(<class 'list'>, {'Baking': ['Adam'], 'Tutoring': ['Betty']}))]

但我需要输出(格式为可读性,不是要求):(按字母顺序)

[(5, [('Cleaning', ['Charles'])]),
(4, [('Cleaning', ['Adam', 'Diane'])]),
(3, [('Cleaning', ['Betty']), ('Gardening', ['Diane'])]),
(2, [('Gardening', ['Betty']), ('Laundry', ['Diane']),
 ('Plumbing', ['Charles']), ('Tutoring', ['Adam'])]),
(1, [('Baking', ['Adam']), ('Tutoring', ['Betty'])])]

我是否必须第三次调用 sorted 才能做到这一点?

【问题讨论】:

  • 不是在打印对象的类,而是在打印list。你的意思是用order_skills = defaultdict(lambda:defaultdict([])) 而不是defaultdict(lambda: defaultdict(list))
  • defaultdict(lambda:defaultdict([])) 会破坏我的代码并给我一个 TypeError: first argument must be callable or none

标签: python sorting defaultdict


【解决方案1】:

由于评分范围在 1 到 5 之间,您可以构建一个包含技能键名列表的评分键名字典,然后遍历评分以在线性时间内按技能提取姓名:

by_skill = {}
for name, skills in db1.items():
    for skill, rating in skills.items():
        by_skill.setdefault(rating, {}).setdefault(skill, []).append(name)
print([
    (
        rating,
        sorted(
            (skill, sorted(names)) for skill, names in by_skill.get(rating, {}).items()
        )
    )
    for rating in range(5, 0, -1)
])

这个输出:

[(5, [('Cleaning', ['Charles'])]), (4, [('Cleaning', ['Adam', 'Diane'])]), (3, [('Cleaning', ['Betty']), ('Gardening', ['Diane'])]), (2, [('Gardening', ['Betty']), ('Laundry', ['Diane']), ('Plumbing', ['Charles']), ('Tutoring', ['Adam'])]), (1, [('Baking', ['Adam']), ('Tutoring', ['Betty'])])]

【讨论】:

  • 打印的列表必须按字母顺序递增,这就是我尝试使用排序的原因。有没有办法用你的解决方案做到这一点?
  • 我明白了。我已经更新了我的答案,以便它按字母顺序对技能和名称进行排序。
猜你喜欢
  • 1970-01-01
  • 2022-10-06
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2013-10-11
相关资源
最近更新 更多