由于[4, 5, 6]
并且[2, 3, 1]
服务于两个不同的目的,我将创建一个带有两个参数的函数:要重新排序的列表,以及排序将决定顺序的列表.我只会返回重新排序的列表.
这个答案有三个不同解决方案的时间,用于创建排序的排列列表.使用最快的选项提供此解决方案:
def pyargsort(seq):
return sorted(range(len(seq)), key=seq.__getitem__)
def using_pyargsort(a, b):
"Reorder the list a the same way as list b would be reordered by a normal sort"
return [a[i] for i in pyargsort(b)]
print using_pyargsort([4, 5, 6], [2, 3, 1]) # [6, 4, 5]
Run Code Online (Sandbox Code Playgroud)
该pyargsort
方法的灵感来自于numpy argsort
方法,它可以更快地完成同样的操作.Numpy还具有高级索引操作,可以将数组用作索引,从而可以非常快速地重新排序数组.
因此,如果您对速度的需求很大,那么可以假设这个numpy解决方案会更快:
import numpy as np
def using_numpy(a, b):
"Reorder the list a the same way as list b would be reordered by a normal sort"
return np.array(a)[np.argsort(b)].tolist()
print using_numpy([4, 5, 6], [2, 3, 1]) # [6, 4, 5]
Run Code Online (Sandbox Code Playgroud)
但是,对于短列表(长度<1000),此解决方案实际上比第一个慢.这是因为我们首先将a
和b
列表array
转换为然后将结果转换回返回list
之前.如果我们假设你在整个应用程序中使用numpy数组,这样我们就不需要来回转换了,我们得到了这个解决方案:
def all_numpy(a, b):
"Reorder array a the same way as array b would be reordered by a normal sort"
return a[np.argsort(b)]
print all_numpy(np.array([4, 5, 6]), np.array([2, 3, 1])) # array([6, 4, 5])
Run Code Online (Sandbox Code Playgroud)
该all_numpy
功能的执行速度比using_pyargsort
功能快10倍.
以下对数图将这三种解决方案与其他答案中的两种替代解决方案进行了比较.参数是两个等长的随机混洗范围,并且函数都接收相同排序的列表.我只计算函数执行的时间.为了说明的目的,我为每个numpy解决方案添加了额外的图形行,其中加载numpy的60 ms开销被添加到时间.
正如我们所看到的,这种全能的解决方案比其他解决方案高出一个数量级.相比之下,从python转换list
回来会using_numpy
大大减慢解决方案的速度,但对于大型列表,它仍然胜过纯python.
对于大约1'000'000的列表长度,using_pyargsort
需要2.0秒,using_nympy
+开销仅为1.3秒,而all_numpy
+开销为0.3秒.
您描述的排序不是很容易实现.我能想到的唯一方法就是zip
用来创建你不想创建的列表:
lst = [[4,5,6],[2,3,1]]
# key = operator.itemgetter(1) works too, and may be slightly faster ...
transpose_sort = sorted(zip(*lst),key = lambda x: x[1])
lst = zip(*transpose_sort)
Run Code Online (Sandbox Code Playgroud)
有这种约束的原因吗?
(另请注意,如果您真的想要,可以在一行中执行此操作:
lst = zip(*sorted(zip(*lst),key = lambda x: x[1]))
Run Code Online (Sandbox Code Playgroud)
这也会产生一个元组列表.如果你真的想要一个列表列表,你可以map
得到结果:
lst = map(list, lst)
Run Code Online (Sandbox Code Playgroud)
或者列表理解也会起作用:
lst = [ list(x) for x in lst ]
Run Code Online (Sandbox Code Playgroud)