4

i've looked up similar posts to these and the examples people have posted are throwing the same error at me just as my own version is. I keep getting the error "list indices must be integers, not float." I believe my logic behind getting the median is fine but I can't figure out how to get around this. I understand that this is happening because 5/2 = 2.5 and that isn't a valid index, but how am I supposed to get the median of an even list in that case?

My short code is:

def median(lst):

    lst.sort()

    a = len(lst)

    if a % 2 == 0:
        b = lst[len(lst)/2]
        c = lst[(len(lst)/2)-1]
        d = (b + c) / 2
        return d

    if a % 2 > 0:
        return lst[len(lst)/2]

myList = [1,8,10,11,5]
myList2 = [10,5,7,2,1,8]

print(median(myList))
print(median(myList2))

I tried doing this to fix it but still ended up with same error:

def median(list):

    list.sort()

    a = float(len(list))

    if a % 2 == 0:
        b = float(list[len(list)/2])
        c = float(list[(len(list)/2)-1])
        d = (b + c) / 2.0
        return float(d)

    if a % 2 > 0:
        return float(list[len(list)/2])

myList = [1,8,10,11,5]
myList2 = [10,5,7,2,1,8]

print(median(myList))
print(median(myList2))
SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
M.G
  • 440
  • 1
  • 3
  • 10

7 Answers7

6

A better way to do in python version 3 is with module statistics

import statistics

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

statistics.median(items)

If you want a function, try this.

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

You can also use numpy.median() which i often use:

import numpy
def median(l):
    return numpy.median(numpy.array(l))
White Shadow
  • 444
  • 2
  • 10
  • 26
5

Exception is caused by / operator that returns float on Python 3.x. Use integer division // instead when calculating the index:

>>> 2 / 1
2.0
>>> 2 // 1
2
niemmi
  • 17,113
  • 7
  • 35
  • 42
2

There are some other answers about fixing the float problem. However to answer your question about even length lists, from Google:

The median is also the number that is halfway into the set. To find the median, the data should be arranged in order from least to greatest. If there is an even number of items in the data set, then the median is found by taking the mean (average) of the two middlemost numbers.

So you would need to do (list[len/2]*list[(len/2)-1])/2 (minus 1 for 0 indexed arrays, plus 1 for 1 indexed arrays)

Chris G
  • 359
  • 2
  • 9
  • I second this answer as it actually points out that the median value of an even length data set is not simply calculated by taking the value at the next even index above / below. – s1hofmann Jun 08 '16 at 15:35
2

Used np.mean as math.floor

import math
import numpy as np

def get_median(list_):
    list_.sort()
    if len(list_)%2 == 0:
        return np.mean([list_[(len(list_)//2)-1], list_[((len(list_)//2))]])
    else:
        return list_[math.floor(len(list_)/2)]
1

Use math.floor,

import math

l = sorted([1,8,10,11,5])
m = l[int(math.floor(len(myList)/2))]       # 8

As mentioned by @schwobaseggl, just use l[len(l)//2].


Or use the Python module statistics for Python 3.4+,

>>> from statistics import median
>>> median([1,8,10,11,5])
8
SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
1

Of the top of my head, this seems like valid approach, avoiding modulo altogether:

def median(lst):
    lst.sort()
    half = len(lst)//2  # integer division
    b = lst[half]
    c = lst[-half-1]  # for odd lengths, b == c
    return (b + c) / 2

> median([1,8,10,11,5])
8.0
> median([10,5,7,2,1,8])
6.0
user2390182
  • 72,016
  • 6
  • 67
  • 89
0

This was my approach. When calculating the variable med you just make the divisor a float to get a decimal back.

def median(num_list):
    num_list.sort()
    x = len(num_list)
    if x % 2 == 0:     # for even lengths
        a = num_list[x / 2]
        b = num_list[(x / 2) - 1]
        med = float((a + b) / 2.0)
        return "Even listed median is %s" % med
    else:              # for odd lengths
        index = x / 2
        return "Odd listed median is %s" % num_list[index]
print median([1,2,3,4])
Jekt
  • 25
  • 1
  • 6