尝试从以下字典中为每个键获取最大的频率值:
{'cars': ['sedan', 'sedan', 'van', 'van'], 'snack': ['chips', 'chips', 'cheetos'], 'computer': ['laptop', 'desktop']}
但是,如果有 tie ,则应按字母顺序返回值列表中的第一个单词。
已经尝试过collections.Counter
,但是如果有平局,它将返回任意值。我还知道,有些帖子显示了如何查找最常用的字典值,但是在打成平局的情况下它们并没有解决字母顺序问题。
例如,上述字典应返回:
{'cars': 'sedan', 'snack':'chips', 'computer':'desktop'}
非常感谢您的帮助。
答案 0 :(得分:3)
这看起来很简单,但需要进行大量转换才能获得正确的结果
使用counter
是正确的方法,但是您必须对项目进行排序。请注意,most_common
方法无效/非常有用,因为使用1
作为参数来限制结果数量可以选择“错误”条目:
{k : collections.Counter(v).most_common(1) for k,v in d.items()} # no dice!!
产量{'cars': [('sedan', 2)], 'computer': [('desktop', 1)], 'snack': [('chips', 2)]}
接近我们想要的水平,但也可以在其他时间选择'van'
...
自然排序也不起作用,因为您需要根据出现的次数(倒置的)然后按字母数字键进行排序。您需要一个复杂的排序键:
lambda i : (-i[1],i[0])
({i
是键/值对,因此-i[1]
是相反数目的元素,因此,最高的数目在前,而i[0]
是名称)
然后,选择第一个值和该值的第一项(丢弃计数)
赞:
import collections
d = {'cars': ['sedan', 'sedan', 'van', 'van'], 'snack': ['chips', 'chips', 'cheetos'], 'computer': ['laptop', 'desktop']}
c = {k : sorted(collections.Counter(v).items(),
key = lambda i : (-i[1],i[0]))[0][0] for k,v in d.items() if v}
结果:
>>> c
{'cars': 'sedan', 'computer': 'desktop', 'snack': 'chips'}
请注意,if v
条件不受“一个列表为空”情况的保护(否则,在选择第一个元素时它将引发IndexError
)。
答案 1 :(得分:1)
我建议不是单线。单线可能会证明您是一名优秀的编码人员,但实际上是不良的编码风格。
这是编写辅助函数的最佳时机:
from collections import Counter
def most_common(items):
# Protect against empty input
if not items:
return None
# This does the actual computing
counter = Counter(items)
# Initialize the result variables
result, max_count = counter.most_common(1)[0]
# most_common are sorted, so we can stop once the count is not the max count
for elem, count in counter.most_common():
if count != max_count:
break
# replace with alphabetically better result
result = min(result,elem)
return result
inp = {'cars': ['sedan', 'sedan', 'van', 'van'], 'snack': ['chips', 'chips', 'cheetos'], 'computer': ['laptop', 'desktop']}
results = {key: most_common(val) for key, val in inp.items()}
print(results)
# {'cars': 'sedan', 'snack': 'chips', 'computer': 'desktop'}