代码之家  ›  专栏  ›  技术社区  ›  Colin

求两个值的最大值和最小值的最佳方法

  •  10
  • Colin  · 技术社区  · 14 年前

    我有一个传递两个值的函数,然后在这些值的范围内迭代。这些值可以按任意顺序传递,所以我需要先找出哪个值最低。我的函数是这样写的:

    def myFunc(x, y):
        if x > y:
            min_val, max_val = y, x
        else:
            min_val, max_val = x, y
        for i in range(min_val, max_val):
        ...
    

    def myFunc(x, y):
       min_val, max_val = sorted([x, y])
       for i in range(min_val, max_val):
       ...
    

    这有多糟?有没有更好的办法,那还是一条线?

    6 回复  |  直到 14 年前
        1
  •  4
  •   John La Rooy    14 年前

    def myFunc(x, y):
        for i in range(*sorted((x, y))):
            ...
    

    不过这要快些

    def myFunc(x, y):
        for i in range(x,y) if x<y else range(y,x):
            ...
    

    def f1(x, y):
        for i in range(min(x, y), max(x, y)):
            pass
    
    def f2(x, y):
        for i in range(*sorted((x, y))):
            pass
    
    def f3(x, y):
        for i in range(x, y) if x<y else range(y, x):
            pass
    
    def f4(x, y):
        if x>y:
            x,y = y,x
        for i in range(x, y):
            pass
    
    def f5(x, y):
        mn,mx = ((x, y), (y, x))[x>y]
        for i in range(x,y):
            pass
    

    基准 (无论顺序如何,f3都是最快的)

    $ python -m timeit -s"import minmax as mm" "mm.f1(1,2)"
    1000000 loops, best of 3: 1.93 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f2(1,2)"
    100000 loops, best of 3: 2.4 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f3(1,2)"
    1000000 loops, best of 3: 1.16 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f4(1,2)"
    100000 loops, best of 3: 1.2 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f5(1,2)"
    1000000 loops, best of 3: 1.58 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f1(2,1)"
    100000 loops, best of 3: 1.88 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f2(2,1)"
    100000 loops, best of 3: 2.39 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f3(2,1)"
    1000000 loops, best of 3: 1.18 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f4(2,1)"
    1000000 loops, best of 3: 1.25 usec per loop
    $ python -m timeit -s"import minmax as mm" "mm.f5(2,1)"
    1000000 loops, best of 3: 1.44 usec per loop
    
        2
  •  15
  •   miku    14 年前

    min max

    def myFunc(x, y):
        min_val, max_val = min(x, y), max(x, y)
    

    min-max 一个简单的版本 if . 由于函数调用开销, 最小值最大值 2.5x 再简单不过了 ;参见 http://gist.github.com/571049

        3
  •  5
  •   Don O'Donnell    14 年前

    x y lo hi ),我同意(为了速度和清晰度):

    def myfunc(x, y):
        lo, hi = (x, y) if x < y else (y, x)
    
    >>> timeit.repeat("myfunc(10, 5)", "from __main__ import myfunc")
    [1.2527812156004074, 1.185214249195269, 1.1886092749118689]
    >>> timeit.repeat("foo(10, 5)", "from __main__ import foo")
    [1.0397177348022524, 0.9580022495574667, 0.9673979369035806]
    >>> timeit.repeat("f3(10, 5)", "from __main__ import f3")
    [2.47303065772212, 2.4192818561823515, 2.4132735135754046]
    
        4
  •  4
  •   John Kugelman Michael Hodel    14 年前

    sorted 一个。聪明但不太聪明。这里有一些其他的选择。

    def myFunc(min, max):
        if min > max: min, max = max, min
    
    def myFunc(x, y):
        min, max = min(x, y), max(x, y)
    
    def myFunc(x, y):
        min, max = [f(x, y) for f in (min, max)]
    

        5
  •  2
  •   AndiDog    14 年前

    一些建议

    def myfunc(minVal, maxVal):
        if minVal > maxVal: minVal, maxVal = maxVal, minVal
    
    def myfunc2(a, b):
        minVal, maxVal = ((a, b), (b, a))[a > b] # :-P
    

    在这种情况下,使用sorted,min/max内置函数或上面的第二个解决方案似乎有些过分。

    记住这一点 range(min, max) min max - 1 !

        6
  •  2
  •   Ian    14 年前

    最佳答案如下:

    def foo(lo, hi):
        if hi < lo: lo,hi = hi,lo
    

    它很清楚,很有意义,而且不会在一堆额外的胶水中模糊意义。它很短。在实践中,它几乎可以肯定与任何其他选择一样快,而且它依赖于最少的聪明。