我有一个嵌套的排行榜,像这样:
[[100, 100, 50, 40, 40, 20, 10, 5], [100, 100, 50, 40, 40, 25, 20, 10]]
我想在 Dense Order Ranking 方法中找到这个排行榜中的排名。 https://en.wikipedia.org/wiki/Ranking#Dense_ranking_.28.221223.22_ranking.29
我想使用排名并将其变成字典,但分数需要保留为键,而排名为值,如下所示:
[{100:1,100:1,50:2,40:3,40:3,20:4,10:5,5:6},{100:1,100:1,50:2,40:3,40:3,25:4,20:5,10:6}]
如何使用 Python3 实现此目的?
最佳答案
如前所述,您期望的数据结构不是字典,因为它包含重复键。相反,您可以创建一个元组列表。您可以使用计数器对象和字典来跟踪看到的项目及其各自的索引以创建该元组。
以下函数是上述方法的可理解实现,可在一次迭代中创建预期结果。
In [38]: from itertools import count
In [38]: def ranker(lst):
...: for sub in lst:
...: seen = {}
...: c = count()
...: next(c)
...: ss = []
...: for j in sub:
...: try:
...: ind = seen[j]
...: except KeyError:
...: ind = seen[j] = next(c)
...: ss.append((j, ind))
...: yield ss
演示:
In [39]: lst
Out[39]: [[100, 100, 50, 40, 40, 20, 10, 5], [100, 100, 50, 40, 40, 25, 20, 10]]
In [40]: list(ranker(lst))
Out[40]:
[[(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (20, 4), (10, 5), (5, 6)],
[(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (25, 4), (20, 5), (10, 6)]]
现在,一种更加 Pythonic 但有点晦涩的方法是不使用 counter
和 try-except
block ,甚至列表并使用 dict.setdefault()
列表理解中的方法如下:
In [43]: def ranker(lst):
...: for sub in lst:
...: seen = {}
...: yield [(j, seen.setdefault(j, len(seen) + 1)) for j in sub]
如果字典中存在第一个参数,则 dict.setdefault()
方法返回相应的值,否则使用第二个参数更新自身 (len(seen) + 1
) 作为它的值并返回它。
演示:
In [44]: list(ranker(lst))
Out[44]:
[[(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (20, 4), (10, 5), (5, 6)],
[(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (25, 4), (20, 5), (10, 6)]]
关于python - 如何找到排行榜中的排名并将其转换为 Python 3 中的字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50406182/