python函数返回一个包含值的字典,以及原始字典中具有该值的相应键列表



我有一个字典,我正在创建一个函数,该函数接受相同的每个值,并用value键创建一个新字典。我有一些例子的文档测试。我相信这可以通过列表理解在一行中完成。

>>> rating = {"bob": "excellent", "barnum": "passing", "beatrice": "satisfactory", "bernice": "passing", "ben": "no pass", "belle": "excellent", "bill": "passing", "bernie": "passing", "baxter": "excellent"}
>>> new_dict(rating) # new_dict is the function
>>> {'excellent': ['bob', 'belle', 'baxter'], 'passing': ['barnum', 'bernice', 'bill', 'bernie'], 'satisfactory': ['beatrice'], 'no pass': ['ben']}

您可以使用itertools.groupby和排序来执行一行:

>>> from itertools import groupby
>>> {k:[x[0] for x in g] for k,g in groupby(sorted(rating.items(), key=lambda x:x[1]),lambda x:x[1])}
{'passing': ['bernice', 'barnum', 'bernie', 'bill'], 'no pass': ['ben'], 'excellent': ['belle', 'baxter', 'bob'], 'satisfactory': ['beatrice']}
>>>

但这是不必要的低效,它需要一个具体化辅助列表的排序操作,而且过于复杂。不要努力写一句俏皮话。编写清晰可读的代码,有效地使用python数据结构。只需使用collections.defaultdict,这是对事物进行分组的规范方法:

>>> from collections import defaultdict
>>> grouper = defaultdict(list)
>>> for k,v in rating.items():
...     grouper[v].append(k)
...
>>> grouper
defaultdict(<class 'list'>, {'passing': ['bernice', 'barnum', 'bernie', 'bill'], 'excellent': ['belle', 'baxter', 'bob'], 'satisfactory': ['beatrice'], 'no pass': ['ben']})
>>>

我认为没有什么好方法可以把它写成一种理解。考虑来自collections模块的defaultdict

>>> from collections import defaultdict
>>> 
>>> result = defaultdict(list)
>>> for k, v in rating.items():
...:    result[v].append(k)
...:    
>>> result
>>> 
defaultdict(list,
{'excellent': ['bob', 'baxter', 'belle'],
'no pass': ['ben'],
'passing': ['barnum', 'bernice', 'bill', 'bernie'],
'satisfactory': ['beatrice']})

这有时间复杂性O(n(,我尝试过的任何理解,比如

>>> {v:[k for k, v_ in rating.items() if v_ == v] for v in rating.values()}
>>> 
{'excellent': ['bob', 'baxter', 'belle'],
'no pass': ['ben'],
'passing': ['barnum', 'bernice', 'bill', 'bernie'],
'satisfactory': ['beatrice']}

在O(n**2(处更差。

使用列表理解尽可能缩短答案。我相信有一种方法可以将函数简化为一行。

def new_dict(rating):
my_dict = dict([(i,[]) for i in set([value for key,value in rating.items()])])
[my_dict[value].append(key) for key,value in rating.items()]
return my_dict
rating = {"bob": "excellent", "barnum": "passing", "beatrice": "satisfactory", "bernice": "passing", "ben": "no pass", "belle": "excellent", "bill": "passing", "bernie": "passing", "baxter": "excellent"}
print(new_dict(rating)) # new_dict is the function

这将打印以下内容的输出:

{'excellent': ['bob', 'belle', 'baxter'], 'passing': ['barnum', 'bernice', 'bill', 'bernie'], 'satisfactory': ['beatrice'], 'no pass': ['ben']}

最新更新