查找两个值的最大值和最小值的最佳方法

12 投票
6 回答
16986 浏览
提问于 2025-04-16 03:53

我有一个函数,它接收两个值,然后在这两个值的范围内进行循环。这两个值可以以任何顺序传入,所以我需要先找出哪个值是最小的。我最开始是这样写这个函数的:

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 个回答

7

因为提问者在问题中使用的是 xy 作为参数(而不是 lohi),所以我建议使用这个方法(这样既快又清晰):

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]
16

minmax 是你编程时的好帮手。

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

补充一下。对比了 min-max 的版本和一个简单的 if 语句。因为调用函数会有额外的时间开销,所以 min-max 的执行时间比简单的 if 要长 2.5倍;具体可以查看 http://gist.github.com/571049

4

除非你需要进行非常细致的优化,不然我建议你就这样做。

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):
        ...

minmax.py

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

撰写回答