在Python中查找列表的中间值

在Python中查找列表的中间值,python,list,sorting,median,python-2.x,python-3.x,Python,List,Sorting,Median,Python 2.x,Python 3.x,如何在Python中找到列表的中间值?列表可以是任意大小,并且不能保证数字按任何特定顺序排列 如果列表包含偶数个元素,则函数应返回中间两个元素的平均值 以下是一些示例(按显示目的排序): sorted()函数对此非常有用。使用排序函数 要对列表排序,只需返回中间值(或平均两个中间值) 值(如果列表包含偶数个元素) 您可以使用list.sort来避免创建带有sorted的新列表,并对列表进行适当排序 另外,您不应该将list用作变量名,因为它会隐藏python自己的变量名 (与一起使用): :

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

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

以下是一些示例(按显示目的排序):

sorted()
函数对此非常有用。使用排序函数 要对列表排序,只需返回中间值(或平均两个中间值) 值(如果列表包含偶数个元素)


您可以使用
list.sort
来避免创建带有
sorted
的新列表,并对列表进行适当排序

另外,您不应该将
list
用作变量名,因为它会隐藏python自己的变量名

(与一起使用):



:


对于,请使用:

Python 3.4具有:

返回数值数据的中值(中间值)

当数据点数为奇数时,返回中间数据点。 当数据点数为偶数时,通过取两个中间值的平均值对中值进行插值:

>>> median([1, 3, 5])
3
>>> median([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)

这是非常不理想的,但即使是经过优化的版本也不太可能比Tim Sort(CPython内置的
Sort
)表现更好,因为它速度非常快。我以前试过,但失败了。

我为数字列表定义了一个中值函数

def median(numbers):
    return (sorted(numbers)[int(round((len(numbers) - 1) / 2.0))] + sorted(numbers)[int(round((len(numbers) - 1) // 2.0))]) / 2.0

这里有一个更干净的解决方案:

def median(lst):
    quotient, remainder = divmod(len(lst), 2)
    if remainder:
        return sorted(lst)[quotient]
    return sum(sorted(lst)[quotient - 1:quotient + 1]) / 2.

注:答案更改为将建议纳入评论。

中值函数

def median(midlist):
    midlist.sort()
    lens = len(midlist)
    if lens % 2 != 0: 
        midl = (lens / 2)
        res = midlist[midl]
    else:
        odd = (lens / 2) -1
        ev = (lens / 2) 
        res = float(midlist[odd] + midlist[ev]) / float(2)
    return res
我在上发布了我的解决方案,这比使用sort()要快一点。我的解决方案每列使用15个数字,速度~5N比每列使用5个数字的速度~10N快。最佳速度为~4N,但我可能错了

根据Tom在评论中的要求,我在这里添加了代码,以供参考。我相信速度的关键部分是每列使用15个数字,而不是5个

#!/bin/pypy
#
# TH @stackoverflow, 2016-01-20, linear time "median of medians" algorithm
#
import sys, random


items_per_column = 15


def find_i_th_smallest( A, i ):
    t = len(A)
    if(t <= items_per_column):
        # if A is a small list with less than items_per_column items, then:
        #
        # 1. do sort on A
        # 2. find i-th smallest item of A
        #
        return sorted(A)[i]
    else:
        # 1. partition A into columns of k items each. k is odd, say 5.
        # 2. find the median of every column
        # 3. put all medians in a new list, say, B
        #
        B = [ find_i_th_smallest(k, (len(k) - 1)/2) for k in [A[j:(j + items_per_column)] for j in range(0,len(A),items_per_column)]]

        # 4. find M, the median of B
        #
        M = find_i_th_smallest(B, (len(B) - 1)/2)


        # 5. split A into 3 parts by M, { < M }, { == M }, and { > M }
        # 6. find which above set has A's i-th smallest, recursively.
        #
        P1 = [ j for j in A if j < M ]
        if(i < len(P1)):
            return find_i_th_smallest( P1, i)
        P3 = [ j for j in A if j > M ]
        L3 = len(P3)
        if(i < (t - L3)):
            return M
        return find_i_th_smallest( P3, i - (t - L3))


# How many numbers should be randomly generated for testing?
#
number_of_numbers = int(sys.argv[1])


# create a list of random positive integers
#
L = [ random.randint(0, number_of_numbers) for i in range(0, number_of_numbers) ]


# Show the original list
#
# print L


# This is for validation
#
# print sorted(L)[int((len(L) - 1)/2)]


# This is the result of the "median of medians" function.
# Its result should be the same as the above.
#
print find_i_th_smallest( L, (len(L) - 1) / 2)
#/垃圾桶
#
#TH@stackoverflow,2016-01-20,线性时间“中间值”算法
#
导入系统,随机
每列项目数=15
def find_i_th_最小(A,i):
t=len(A)
if(tm}
#6.递归地找出上面哪个集合具有A的第i个最小值。
#
P1=[j为j,如果jM时,j代表A中的j]
L3=透镜(P3)
如果(i<(t-L3)):
返回M
返回find_i_th_最小值(P3,i-(t-L3))
#测试时应随机生成多少个数字?
#
数量=整数(sys.argv[1])
#创建一个随机正整数列表
#
L=[random.randint(0,数字中的数字)表示范围(0,数字中的数字)]
#显示原始列表
#
#打印L
#这是为了验证
#
#打印排序(L)[int((len(L)-1)/2]
#这是“中位数”功能的结果。
#其结果应与上述相同。
#
打印最小(L,(len(L)-1)/2的查找

下面是我在Codecademy中的这个练习中想到的:

def median(data):
    new_list = sorted(data)
    if len(new_list)%2 > 0:
        return new_list[len(new_list)/2]
    elif len(new_list)%2 == 0:
        return (new_list[(len(new_list)/2)] + new_list[(len(new_list)/2)-1]) /2.0

print median([1,2,3,4,5,9])

下面是一种不用
median
函数查找中值的繁琐方法:

def median(*arg):
    order(arg)
    numArg = len(arg)
    half = int(numArg/2)
    if numArg/2 ==half:
        print((arg[half-1]+arg[half])/2)
    else:
        print(int(arg[half]))

def order(tup):
    ordered = [tup[i] for i in range(len(tup))]
    test(ordered)
    while(test(ordered)):
        test(ordered)
    print(ordered)


def test(ordered):
    whileloop = 0 
    for i in range(len(ordered)-1):
        print(i)
        if (ordered[i]>ordered[i+1]):
            print(str(ordered[i]) + ' is greater than ' + str(ordered[i+1]))
            original = ordered[i+1]
            ordered[i+1]=ordered[i]
            ordered[i]=original
            whileloop = 1 #run the loop again if you had to switch values
    return whileloop

我在处理浮点值列表时遇到了一些问题。我最终使用了python3中的一个代码段,并且在不导入浮点值的情况下工作得非常好


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

def median(data):
    data.sort()
    mid = len(data) // 2
    return (data[mid] + data[~mid]) / 2
def中值(数组):
如果len(数组)<1:
返回(无)
如果len(数组)%2==0:
中值=(数组[len(数组)//2-1:len(数组)//2+1])
回报总额(中位数)/长度(中位数)
其他:
返回(数组[len(数组)//2])
它非常简单

def median(alist):
    #to find median you will have to sort the list first
    sList = sorted(alist)
    first = 0
    last = len(sList)-1
    midpoint = (first + last)//2
    return midpoint
您可以使用如下返回值
中值=中值(anyList)

函数中值:
如果您需要有关列表分布的其他信息,百分位数方法可能会很有用。中值对应于列表的第50个百分位数:

import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
median_value = np.percentile(a, 50) # return 50th percentile
print median_value 

中位数(和百分位数)更普遍的方法是:

def get_percentile(data, percentile):
    # Get the number of observations
    cnt=len(data)
    # Sort the list
    data=sorted(data)
    # Determine the split point
    i=(cnt-1)*percentile
    # Find the `floor` of the split point
    diff=i-int(i)
    # Return the weighted average of the value above and below the split point
    return data[int(i)]*(1-diff)+data[int(i)+1]*(diff)

# Data
data=[1,2,3,4,5]
# For the median
print(get_percentile(data=data, percentile=.50))
# > 3
print(get_percentile(data=data, percentile=.75))
# > 4

# Note the weighted average difference when an int is not returned by the percentile
print(get_percentile(data=data, percentile=.51))
# > 3.04


返回给定列表中值的简单函数:

def中间值(lst):
lst.sort()#首先对列表进行排序
如果len(lst)%2==0:#检查长度是否为偶数
#应用中间两个之和除以2的公式
返回(lst[len(lst)//2]+lst[(len(lst)-1)//2])/2
其他:
#如果长度为奇数,则获取中间值
返回lst[len(lst)//2]
中值
功能的一些示例:

>>中位数([9,12,20,21,34,80])偶数
20.5
>>>中位数([9,12,80,21,34])奇数
21
如果您想使用库,只需执行以下操作:

导入统计信息 >>>统计学:中位数([9,12,20,21,34,80])#偶数 20.5 >>>统计学:中位数([9,12,80,21,34])奇数 21
只要两行就足够了

def get_median(arr):
    '''
    Calculate the median of a sequence.
    :param arr: list
    :return: int or float
    '''
    arr.sort()
    return arr[len(arr)//2] if len(arr) % 2 else (arr[len(arr)//2] + arr[len(arr)//2-1])/2
做你自己

def median(numbers):
    """
    Calculate median of a list numbers.
    :param numbers: the numbers to be calculated.
    :return: median value of numbers.

    >>> median([1, 3, 3, 6, 7, 8, 9])
    6
    >>> median([1, 2, 3, 4, 5, 6, 8, 9])
    4.5
    >>> import statistics
    >>> import random
    >>> numbers = random.sample(range(-50, 50), k=100)
    >>> statistics.median(numbers) == median(numbers)
    True
    """
    numbers = sorted(numbers)
    mid_index = len(numbers) // 2
    return (
        (numbers[mid_index] + numbers[mid_index - 1]) / 2 if mid_index % 2 == 0
        else numbers[mid_index]
    )


if __name__ == "__main__":
    from doctest import testmod

    testmod()
我所做的是:

def median(a):
    a.sort()
    if len(a) / 2 != int:
        return a[len(a) / 2]
    else:
        return (a[len(a) / 2] + a[(len(a) / 2) - 1]) / 2
说明:基本上,如果列表中的项目数是奇数,则返回中间的数字,否则,如果列表为半个偶数,python会自动将较高的数字舍入,因此我们知道之前的数字将减少一个(因为我们对其进行了排序)我们可以加上默认的高数字和低数字,然后除以2来找到媒体
def median(data):
    new_list = sorted(data)
    if len(new_list)%2 > 0:
        return new_list[len(new_list)/2]
    elif len(new_list)%2 == 0:
        return (new_list[(len(new_list)/2)] + new_list[(len(new_list)/2)-1]) /2.0

print median([1,2,3,4,5,9])
def median(*arg):
    order(arg)
    numArg = len(arg)
    half = int(numArg/2)
    if numArg/2 ==half:
        print((arg[half-1]+arg[half])/2)
    else:
        print(int(arg[half]))

def order(tup):
    ordered = [tup[i] for i in range(len(tup))]
    test(ordered)
    while(test(ordered)):
        test(ordered)
    print(ordered)


def test(ordered):
    whileloop = 0 
    for i in range(len(ordered)-1):
        print(i)
        if (ordered[i]>ordered[i+1]):
            print(str(ordered[i]) + ' is greater than ' + str(ordered[i+1]))
            original = ordered[i+1]
            ordered[i+1]=ordered[i]
            ordered[i]=original
            whileloop = 1 #run the loop again if you had to switch values
    return whileloop
def calculateMedian(list):
    data = sorted(list)
    n = len(data)
    if n == 0:
        return None
    if n % 2 == 1:
        return data[n // 2]
    else:
        i = n // 2
        return (data[i - 1] + data[i]) / 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])
def median(array):
    if len(array) < 1:
        return(None)
    if len(array) % 2 == 0:
        median = (array[len(array)//2-1: len(array)//2+1])
        return sum(median) / len(median)
    else:
        return(array[len(array)//2])
def median(x):
    x = sorted(x)
    listlength = len(x) 
    num = listlength//2
    if listlength%2==0:
        middlenum = (x[num]+x[num-1])/2
    else:
        middlenum = x[num]
    return middlenum
def median(alist):
    #to find median you will have to sort the list first
    sList = sorted(alist)
    first = 0
    last = len(sList)-1
    midpoint = (first + last)//2
    return midpoint
import numpy as np
def get_median(xs):
        mid = len(xs) // 2  # Take the mid of the list
        if len(xs) % 2 == 1: # check if the len of list is odd
            return sorted(xs)[mid] #if true then mid will be median after sorting
        else:
            #return 0.5 * sum(sorted(xs)[mid - 1:mid + 1])
            return 0.5 * np.sum(sorted(xs)[mid - 1:mid + 1]) #if false take the avg of mid
print(get_median([7, 7, 3, 1, 4, 5]))
print(get_median([1,2,3, 4,5]))
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] + data[m+1]) / 2
    return med
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
median_value = np.percentile(a, 50) # return 50th percentile
print median_value 
def get_percentile(data, percentile):
    # Get the number of observations
    cnt=len(data)
    # Sort the list
    data=sorted(data)
    # Determine the split point
    i=(cnt-1)*percentile
    # Find the `floor` of the split point
    diff=i-int(i)
    # Return the weighted average of the value above and below the split point
    return data[int(i)]*(1-diff)+data[int(i)+1]*(diff)

# Data
data=[1,2,3,4,5]
# For the median
print(get_percentile(data=data, percentile=.50))
# > 3
print(get_percentile(data=data, percentile=.75))
# > 4

# Note the weighted average difference when an int is not returned by the percentile
print(get_percentile(data=data, percentile=.51))
# > 3.04

def get_median(arr):
    '''
    Calculate the median of a sequence.
    :param arr: list
    :return: int or float
    '''
    arr.sort()
    return arr[len(arr)//2] if len(arr) % 2 else (arr[len(arr)//2] + arr[len(arr)//2-1])/2
def median(numbers):
    """
    Calculate median of a list numbers.
    :param numbers: the numbers to be calculated.
    :return: median value of numbers.

    >>> median([1, 3, 3, 6, 7, 8, 9])
    6
    >>> median([1, 2, 3, 4, 5, 6, 8, 9])
    4.5
    >>> import statistics
    >>> import random
    >>> numbers = random.sample(range(-50, 50), k=100)
    >>> statistics.median(numbers) == median(numbers)
    True
    """
    numbers = sorted(numbers)
    mid_index = len(numbers) // 2
    return (
        (numbers[mid_index] + numbers[mid_index - 1]) / 2 if mid_index % 2 == 0
        else numbers[mid_index]
    )


if __name__ == "__main__":
    from doctest import testmod

    testmod()
def median(a):
    a.sort()
    if len(a) / 2 != int:
        return a[len(a) / 2]
    else:
        return (a[len(a) / 2] + a[(len(a) / 2) - 1]) / 2
def median(l):
        l.sort()
        lent = len(l)
        if (lent%2)==0:
            m = int(lent/2)
            result = l[m]
        else:
            m = int(float(lent/2) -0.5)
            result = l[m]
        return ('median is: {}'.format(result))