我有一个整数列表,例如:
my_list = [5, 2, 4, 9]
我想要一个列表,其中包含每个元素在排序后出现在列表中的位置。所以在上面的例子中,我想要这个结果:
>>> sorted(my_list)
[2, 4, 5, 9]
>>> magnitude(my_list)
[2, 0, 1, 3]
...因为排序后:
5
最终到位2
2
最终到位0
4
最终到位1
9
最终到位3
我怎样才能做到这一点?
我有一个整数列表,例如:
my_list = [5, 2, 4, 9]
我想要一个列表,其中包含每个元素在排序后出现在列表中的位置。所以在上面的例子中,我想要这个结果:
>>> sorted(my_list)
[2, 4, 5, 9]
>>> magnitude(my_list)
[2, 0, 1, 3]
...因为排序后:
5
最终到位2
2
最终到位0
4
最终到位1
9
最终到位3
我怎样才能做到这一点?
In [8]: L = [5,2,4,9]
In [9]: LL = sorted(L)
In [10]: LL
Out[10]: [2, 4, 5, 9]
In [11]: sorted(enumerate(LL), key=lambda t: L.index(t[1]))
Out[11]: [(2, 5), (0, 2), (1, 4), (3, 9)]
In [12]: [s[0] for s in sorted(enumerate(LL), key=lambda t: L.index(t[1]))]
Out[12]: [2, 0, 1, 3]
我们可以通过对序列的枚举进行排序来获得解决方案的一半——例如:
>>> from operator import itemgetter
>>> second_item = itemgetter(1)
>>> my_list = [5, 2, 4, 9]
>>> sorted(enumerate(my_list), key=second_item)
[(1, 2), (2, 4), (0, 5), (3, 9)]
如您所见,结果列表中的每一对都具有(original_position, sorted_item)
... 形式,例如,5
最初位于 position 0
。
我们可以编写一个只返回那些原始位置的函数:
def order(s):
return [t[0] for t in sorted(enumerate(s), key=second_item)]
让我们确保它有效:
>>> order(my_list)
[1, 2, 0, 3]
聪明的一点是,现在我们在它自己的结果上再次运行相同的函数:
>>> order([1, 2, 0, 3])
[2, 0, 1, 3]
要了解这里发生了什么,让我们回过头来看看order()
实际在做什么:
>>> sorted(enumerate([1, 2, 0, 3]), key=second_item)
[(2, 0), (0, 1), (1, 2), (3, 3)]
同样,每一对都具有 形式(original_position, sorted_item)
,因此我们有效地将位置排序回其原始顺序并查看它们的最终位置。
我们现在需要做的就是将双重使用包装order()
在它自己的函数中,我们就完成了:
from operator import itemgetter
second_item = itemgetter(1)
def order(s):
return [t[0] for t in sorted(enumerate(s), key=second_item)]
def magnitude(s):
return order(order(s))
......它正在行动:
>>> magnitude([5, 2, 4, 9])
[2, 0, 1, 3]