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

Python 找到两个值的最大值和最小值的最佳方法,python,Python,我有一个函数,它传递两个值,然后在这些值的范围内迭代。这些值可以按任意顺序传递,因此我需要先找到最低的值。我的函数是这样写的: 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 myFu

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

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):
   ...
这有多糟?还有更好的办法吗?还是一句话?

而且是你的朋友

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


编辑。在一个简单的
if
的基础上对
min-max
版本进行基准测试。由于函数调用开销,
minmax
比简单的
if
花费的
2.5x
更长;参见

我喜欢排序的一个。聪明但不太聪明。这里有一些其他的选择

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)]
我承认最后一个有点傻。

一些建议

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,在这种情况下,上面的最小/最大内置值或第二个解决方案似乎有些过分


记住
range(min,max)
将从
min
迭代到
max-1

除非你需要微优化,否则我只想

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 foo(lo, hi):
    if hi < lo: lo,hi = hi,lo
def foo(低、高):
如果hi

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

既然OP的问题是使用
x
y
作为参数提出的(不是
lo
hi
),我会同意(为了速度和清晰度):

def myfunc(x,y):
lo,hi=(x,y)如果x>>timeit.repeat(“myfunc(10,5)”,“from uuu main_uuuimport myfunc”)
[1.2527812156004074, 1.185214249195269, 1.1886092749118689]
>>>timeit.repeat(“foo(10,5)”,“from uuuu main uuuuu import foo”)
[1.0397177348022524, 0.9580022495574667, 0.9673979369035806]
>>>timeit.repeat(“f3(10,5)”,“从主导入f3”)
[2.47303065772212, 2.4192818561823515, 2.4132735135754046]

我甚至没有想过在一行中完成这项工作。但根据sorted的实现方式,它实际上可能效率较低。我知道C++中的标准库排序是硬编码的,因为最好使用其他的名称,而不是Min和Max,因为它们是Python内置的。
$ 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
def foo(lo, hi):
    if hi < lo: lo,hi = hi,lo
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]