是否有更多的pythonic,更快的想要按值排名字典并平均非唯一值的排名。我的方法:
d = {'a':5,'b':5,'c':5,'d':1,'e':6}
ordered_keys = sorted(d, key=d.get)
ordered_v = [d[k] for k in ordered_keys]
value_rank = [(ordered_v.index(v)+1)+(ordered_v.count(v)-1)/2 for v in ordered_v]
ranked_key_list = zip(ordered_keys,value_rank)
[('d', 1), ('a', 3), ('c', 3), ('b', 3), ('e', 5)]
关于排序词典的广泛讨论非常有用:python dictionary values sorting
答案 0 :(得分:3)
你所拥有的是非常好的,我怀疑有一个更短的解决方案。
就效率而言,重复使用list.index()
和list.count()
可能会降低大数据集的速度。
如果您要为大量数据执行此操作,那么这个替代实现应该更有效:
from itertools import groupby
d = {'a':5,'b':5,'c':5,'d':1,'e':6}
ranked_key_list = []
i = 1
for k, g in groupby(sorted(d.keys(), key=d.get), key=d.get):
g = list(g)
rank = i + (len(g)-1) / 2
ranked_key_list.extend((k, rank) for k in g)
i += len(g)
答案 1 :(得分:3)
你算法的瓶颈是.index和.count是O(n)的事实,因此你的瓶颈是这一行:
value_rank = [(ordered_v.index(v)+1)+(ordered_v.count(v)-1)/2 for v in ordered_v]
使您的整体表现为O(n ^ 2)
我为你做了一个O(n * log(n))算法(瓶颈现在是排序):
import collections
d = {'a':5,'b':5,'c':5,'d':1,'e':6}
my_d = collections.defaultdict(list)
for key, val in d.items():
my_d[val].append(key)
ranked_key_list = []
n = v = 1
for _, my_list in sorted(my_d.items()):
v = n + (len(my_list)-1)/2
for e in my_list:
n += 1
ranked_key_list.append((e, v))
答案 2 :(得分:0)
key_list = zip(dict.keys(), dict.values())
ranked_key_list = sorted(key_list, key=lambda x: x[1])
编辑:刚刚意识到我没有做平均值的事情....你能澄清一点吗?如何平均3 5s = 3 ??