我有一个清单:
[55, 41, 45, 43, 60, 47, 33, 70, 42, 42, 44]
我想创建一个新列表,按照它们的顺序对这些项目进行排名:
预期产出:
[7, ,2 ,9 ,10, 4, 11, 3, 6, 1, 5, 8]
尝试了这3个版本的func,但它不能正常工作,不确定为什么?
def argsort(seq):
#return sorted(range(len(seq)), key = seq.__getitem__)
#return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
return [x for x,y in sorted(enumerate(seq), key = lambda x: x[1])]
返回:
[6, 1, 8, 9, 3, 10, 2, 5, 0, 4, 7]
答案 0 :(得分:3)
让我们更准确地定义你的目标:
给定一个数字列表L,创建一个包含L的有效索引的列表M,这样
M[i]
是排序时出现i
元素的索引。如果L的第一个元素出现在索引1处,则显示M
。
现在,列表的有效索引有两种方式:
range(len(L))
:给出一系列数字0 ... len(L)-1 enumerate(L)
:提供一系列元组(0, L[0])... (len(L)-1, L[len(L)-1])
由于您希望在列表索引从1开始的假设下运行(实际上它们在python中从0开始),我们需要做一些偏离设置
range(len(L))
变为`range(1,len(L)+1)enumerate(L)
变为enumerate(L, 1)
(可选参数告诉enumerate
开始编号为1)由于我们也需要列表项,因此我们使用enumerate
,而不是使用range
并进行查找(我个人更喜欢这种方法,但两者都有效)
现在,我们可以得到一个元组列表,其中每个元组包含L中元素的索引和L中的对应元素。我们需要按元素本身对其进行排序。这可以通过调用sorted
来完成,可选的key
参数解释我们应该按元组的第二个元素排序(operator.itemgetter(1)
正是这样说的。)
一旦我们有了这样的元组的排序列表,我们需要做的就是提取每个元组的第一个元素(L中的索引),我们可以使用list-comprehension [i[0] for i in mylist]
,或等价{{ 1}}
将所有这些元素放在一起,我们得到以下内容
[operator.itemgetter(0)(t) for t in mylist]