2

我正在寻找替代或更简洁的方法来返回三个唯一值的中间值。我现在拥有的是一个功能:

def middle(x, y, z):
    if x > y and x < z:
        return x
    if y > x and y < z:
        return y
    return z

有更好的吗?

4

6 回答 6

9
def middle(x, y, z):
    return sorted([x, y, z])[1]

这应该返回中间数。但是,如果您实际上是指最大数量

def maximum(x, y, z):
    return max([x, y, z])

编辑:正如 abarnert 在评论部分所建议的那样,而不是y>x and x<zuse x < y < z,它更具可读性和 pythonic。

于 2013-11-12T07:06:23.417 回答
3

对于 Python 3.4,statistics.median在标准库中:

import statistics

def middle(x, y, z):
    return statistics.median((x, y, z))

在 3.1-3.3 之后,您pip install stats

import stats

def middle(x, y, z):
    return stats.median((x, y, z))

我相信 2.6-2.7 的反向移植正在开发中,但还不存在。(对于 2.5 或 3.0,只需升级即可。)

当然,如果您有 4 个值,则必须确定“中间”的含义;median将使用两个中间值的平均值,但您可能想要不同的东西。

于 2013-11-12T07:10:47.000 回答
2
def middle(x, y, z):
    return x + y + z - max(x, y, z) - min(x, y, z)

就是图个好玩儿。

于 2013-11-12T07:08:49.983 回答
1

纯娱乐…

我们真的不需要对所有三个值进行排序;我们只需要在遍历整个列表时跟踪最大的 2 个,对吗?

一般来说,这很有用,所以标准库有一种方法可以做到这一点:heapq.nlargest函数。

def middle(x, y, z):
    return heapq.nlargest(2, (x, y, z))[-1]

在实践中,堆比对列表进行排序要慢得多,所以除非列表非常大(3 远不够大)并且您需要记住的元素数量非常少(2/3rds 远不够小),这实际上会让你慢很多。快速测试将显示:

In [66]: %timeit heapq.nlargest(2, [1,2,3])[1]
100000 loops, best of 3: 2.78 us per loop

In [67]: %timeit sorted([1,2,3])[1]
1000000 loops, best of 3: 770 ns per loop

所以,不要在这里使用它,而是将它保存在你的工具箱中,以备下次需要 500000 中的 10 个最高分时使用。

于 2013-11-12T07:38:50.780 回答
1

为了娱乐:

def middle(x, y, z):
    if x < y:
        if y < z:
            return y
        elif x < z:
            return z
        else:
            return x
    else:
        if x < z:
            return x
        elif y > z:
            return y
        else:
            return z
于 2013-11-12T08:18:49.057 回答
0

您还可以制作某种中值函数,它不仅适用于 3 个值

def median(list): 
    list = sorted(list) 
    if len(list) % 2 == 0: 
        n = len(list)//2 
        return (list[n]+list[n-1])/2 
    else: 
        return list[len(l)//2] 
于 2013-11-12T07:11:35.043 回答