我想知道对变量进行排序的最快方法是什么?我有4个整数变量,我需要快速排名。这个过程需要运行很多次,因此需要快速。我尝试使用一个计数器和counter()。most_common()函数,它运行良好,但比单个变量计数要慢。这是我正在运行的一个例子。
A = 15
B = 10
C = 5
D = 10
def get_highest(A,B,C,D):
count = A
label = 'A'
if B >= count:
count = B
label = 'B'
if C >= count:
count = C
label = 'C'
if D >= count:
count = D
label = 'D'
return count, label
highest, label = get_highest(A,B,C,D)
if label == 'A':
A=0
if label == 'B':
B=0
if label == 'C':
C=0
if label == 'D':
D=0
second_highest, label = get_highest(A,B,C,D)
我一直持续到获得所有变量的排名。我想知道是否有更快的方法来做到这一点?我也想在cython中实现这一点,所以在cython中实现时可以加速的答案将不胜感激。
答案 0 :(得分:2)
这是您的功能的更快替代方案:
import operator
def get_highest(A,B,C,D):
return max(zip((A, B, C, D), 'ABCD'), key=operator.itemgetter(0))
但是,如果你的目标是将最大值变量归零,那么你可能最好让这个函数做得更多:
def max_becomes_zero(A, B, C, D):
temp = [A, B, C, D]
maxind, maxval = max(enumerate(temp), key=operator.itemgetter(1))
maxname = 'ABCD'[maxind]
temp[maxind] = 0
return temp, maxval, maxname
如下调用:
(A, B, C, D), highest, label = max_becomes_zero(A, B, C, D)
补充:有些人可能会怀疑(并且在评论中询问)operator.itemgetter
与lambda的相对速度。答:不要怀疑,衡量。这就是Python标准库中的timeit
模块 ...:
$ python -mtimeit -s'a="something"' 'max(enumerate(a), key=lambda x: x[1])'
1000000 loops, best of 3: 1.56 usec per loop
$ python -mtimeit -s'a="something"; import operator' 'max(enumerate(a), operator.itemgetter(1))'
1000000 loops, best of 3: 0.363 usec per loop
如您所见,在这种特殊情况下(在我的Linux工作站上,使用Python 2.7.9),整个操作的加速度令人印象深刻 - 速度提高了4倍以上,每次重复节省超过1微秒。 / p>
更一般地说,在可行的情况下避免lambda
会让你更开心。
注意:确定实际操作的时间非常重要 - 只需在启动时初始化a
和import
,例如{ {1}}表示-s
表单中命令行(推荐)使用timeit
的标记;我怀疑这个错误显然阻止了评论者重现这些结果(只是猜测,因为评论者不向我们展示了确切的代码,当然)。
答案 1 :(得分:1)
以下在我的机器上花费3μs以下来完成整个排名:
In [43]: [name for (val, name) in sorted(zip((A, B, C, D), "ABCD"))][::-1]
Out[43]: ['A', 'D', 'B', 'C']
In [44]: %timeit [name for (val, name) in sorted(zip((A, B, C, D), "ABCD"))][::-1]
100000 loops, best of 3: 2.71 us per loop
或者这个怎么样(我希望我的比较正确: - )):
def rank1(A, B, C, D):
lA, lB, lC, lD = "A", "B", "C", "D"
if A < B:
A, B, lA, lB = B, A, lB, lA
if C < D:
C, D, lC, lD = D, C, lD, lC
if A < C:
A, C, lA, lC = C, A, lC, lA
if B < D:
B, D, lB, lD = D, B, lD, lB
if B < C:
B, C, lB, lC = C, B, lC, lB
return (A, B, C, D), (lA, lB, lC, lD)
整个排名为770ns:
In [6]: %timeit rank1(A, B, C, D)
1000000 loops, best of 3: 765 ns per loop
答案 2 :(得分:0)
可能值得尝试sort
变量:
ordered = sorted(list(zip("ABCD", (A, B, C, D))), key=lambda x: x[1])
>>> print(ordered)
[('C', 5), ('B', 10), ('D', 10), ('A', 15)]