python - 在 Python 3 中,如何在排行榜中查找排名并将其转换为字典?
问题描述
我有一个嵌套的排行榜,如下所示:
[[100, 100, 50, 40, 40, 20, 10, 5], [100, 100, 50, 40, 40, 25, 20, 10]]
我想用密集顺序排名方法在这个排行榜中找到排名。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
块,甚至是列表和附加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)]]
推荐阅读
- r - foreach %dopar% 到 sparklyr 中?
- javascript - 如何在打字稿中使用条件导入模块的类型?
- python - 如何在python中的if ... else语句中编写if else?
- r - 在 dplyr 中删除具有特定列值的行
- liquid - 如何在 Liquid 中执行重复的产品条件?
- java - 我想用给定的用户输入创建一个数组的条形图
- python - 当其他数组为 NaN 时,Python 2D 数组将值替换为 NaN
- javascript - 键码/在按钮组上向上、向下、向左、向右移动
- python - python反向列表代码中的-1,-1,-1如何工作?我想知道原理
- python - 将数据框中的列复制到特定列的新数据框中