在python中快速排列变量

在python中快速排列变量,python,cython,ranking,Python,Cython,Ranking,我想知道排序变量的最快方法是什么?我有4个整数变量,我需要快速排列它们。这个过程需要运行很多次,所以它需要很快。我试着使用一个计数器和counter()。最常用的()函数,它工作得很好,但比只使用单个变量计数要慢。下面是一个我正在运行的示例 A = 15 B = 10 C = 5 D = 10 def get_highest(A,B,C,D): count = A label = 'A' if B >= count: count = B

我想知道排序变量的最快方法是什么?我有4个整数变量,我需要快速排列它们。这个过程需要运行很多次,所以它需要很快。我试着使用一个计数器和counter()。最常用的()函数,它工作得很好,但比只使用单个变量计数要慢。下面是一个我正在运行的示例

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中实现时能够加速的答案将受到赞赏

这里有一个更快的功能替代方案:

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工作站上,使用Python2.7.9),整个操作的加速令人印象深刻——速度快了4倍多,每次重复节省的时间超过一微秒

更一般地说,只要可行,避免lambda会让你更快乐


注意:实际操作的计时非常重要——将初始操作,如
a
的初始化和
import
仅在启动时进行,即在
-s
标记中(推荐)使用
timeit
命令行中的
python-mtimeit
表单中的
-timeit
;我怀疑这一错误显然阻止了评论者复制这些结果(只是一个猜测,正如评论者所说,当然没有向我们显示正在计时的确切代码)。

这里有一个更快的替代函数:

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工作站上,使用Python2.7.9),整个操作的加速令人印象深刻——速度快了4倍多,每次重复节省的时间超过一微秒

更一般地说,只要可行,避免lambda会让你更快乐


注意:实际操作的计时非常重要——将初始操作,如
a
的初始化和
import
仅在启动时进行,即在
-s
标记中(推荐)使用
timeit
命令行中的
python-mtimeit
表单中的
-timeit
;我怀疑这一错误显然阻止了评论者复制这些结果(正如评论者所说的只是猜测,当然不是向我们显示正在计时的确切代码)。

可能值得尝试对变量进行排序:

ordered = sorted(list(zip("ABCD", (A, B, C, D))), key=lambda x: x[1])

>>> print(ordered)
[('C', 5), ('B', 10), ('D', 10), ('A', 15)]

可能值得尝试对变量进行排序:

ordered = sorted(list(zip("ABCD", (A, B, C, D))), key=lambda x: x[1])

>>> print(ordered)
[('C', 5), ('B', 10), ('D', 10), ('A', 15)]

以下内容在我的机器上执行整个排名需要低于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
In [6]: %timeit rank1(A, B, C, D)
1000000 loops, best of 3: 765 ns per loop
或者这个怎么样(我希望我的比较是正确的:-):


以下内容在我的机器上执行整个排名需要低于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
In [6]: %timeit rank1(A, B, C, D)
1000000 loops, best of 3: 765 ns per loop
或者这个怎么样(我希望我的比较是正确的:-):


为什么不使用阵列?你怎么知道什么更快?你是如何计算你尝试过的不同事物的时间的?为什么不使用数组?你如何知道什么更快?你是如何计算你尝试过的不同事情的时间的?是
operator.itemgetter(1)
(使用导入操作符)比
lambda x:x[1]
?Kasra,最好用
python-mtimeit
来测量它。我最好编辑答案以显示如何做到这一点…我这样做lambda更快,
使用运算符:0.0570709705353使用lambda:0.00878500938416
用于
timeit(stmt=s1,number=100000
如果您了解原因,我将不胜感激亲爱的alex!@Kasra,您的数据无法解释(什么是
s1
?关闭参数在哪里?)。现在请参见我的答案。您既不显示
s1
也不显示
s2
,因此最有可能的是您错误地重复了诸如“importis
操作符.itemgetter(1)
(带导入操作符)比
lambda x:x[1]更快的操作
?@Kasra,最好用
python-mtimeit
来测量它。我最好编辑答案来说明如何做到这一点…我这样做lambda更快,
使用操作符:0.05709705353使用lambda:0.00878500938416
用于
timeit(stmt=s1,number=100000
如果您了解原因,我将不胜感激亲爱的alex!@Kasra,您的数据无法解释(什么是
s1
?接近点在哪里?-)。请参见我的答案。您没有显示
s1
s2
,因此很可能是您错误地重复了诸如“导入”之类的操作