在Python中如何找到列表的中值?列表可以是任意大小的,并且数字不保证是任何特定的顺序。

如果列表包含偶数个元素,则函数应返回中间两个元素的平均值。

以下是一些例子(为了便于展示,进行了排序):

median([1]) == 1
median([1, 1]) == 1
median([1, 1, 2, 4]) == 1.5
median([0, 2, 5, 6, 8, 9, 9]) == 6
median([0, 0, 0, 0, 4, 4, 6, 8]) == 2

当前回答

Python 3.4有statistics.median:

返回数值数据的中位数(中间值)。 当数据点数为奇数时,返回中间的数据点。 当数据点数为偶数时,通过取两个中间值的平均值来插值中位数: >>>中位数([1,3,5]) 3. >>>中位数([1,3,5,7]) 4.0

用法:

import statistics

items = [6, 1, 8, 2, 3]

statistics.median(items)
#>>> 3

它对类型也非常小心:

statistics.median(map(float, items))
#>>> 3.0

from decimal import Decimal
statistics.median(map(Decimal, items))
#>>> Decimal('3')

其他回答

如果需要更快的平均情况运行时间,可以尝试快速选择算法。Quickselect具有平均(和最佳)情况性能O(n),尽管在糟糕的一天它可能会以O(n²)结束。

下面是一个随机选择枢轴的实现:

import random

def select_nth(n, items):
    pivot = random.choice(items)

    lesser = [item for item in items if item < pivot]
    if len(lesser) > n:
        return select_nth(n, lesser)
    n -= len(lesser)

    numequal = items.count(pivot)
    if numequal > n:
        return pivot
    n -= numequal

    greater = [item for item in items if item > pivot]
    return select_nth(n, greater)

你可以简单地把它变成一个方法来寻找中位数:

def median(items):
    if len(items) % 2:
        return select_nth(len(items)//2, items)

    else:
        left  = select_nth((len(items)-1) // 2, items)
        right = select_nth((len(items)+1) // 2, items)

        return (left + right) / 2

这是非常未优化的,但即使是一个优化的版本也不太可能超过Tim Sort (CPython的内置排序),因为它真的很快。我以前试过,但失败了。

函数值:

def median(d):
    d=np.sort(d)
    n2=int(len(d)/2)
    r=n2%2
    if (r==0):
        med=d[n2] 
    else:
        med=(d[n2] + d[n2+1]) / 2
    return med

当然,你可以使用内置函数,但如果你想创建自己的函数,你可以这样做。这里的技巧是使用~运算符将正数转换为负数。例如~2 -> -3和在Python中使用负in For list将从末尾开始计数。如果你有mid == 2,那么它会从开始取第三个元素,从结束取第三个元素。

def median(data):
    data.sort()
    mid = len(data) // 2
    return (data[mid] + data[~mid]) / 2
def midme(list1):

    list1.sort()
    if len(list1)%2>0:
            x = list1[int((len(list1)/2))]
    else:
            x = ((list1[int((len(list1)/2))-1])+(list1[int(((len(list1)/2)))]))/2
    return x


midme([4,5,1,7,2])

试试这个

import math
def find_median(arr):
    if len(arr)%2==1:
        med=math.ceil(len(arr)/2)-1
        return arr[med]
    else:
        return -1
print(find_median([1,2,3,4,5,6,7,8]))