Median: Error in my code


#1

It says median[1] returns 0 instead of 1. Here is my code:

def median(_list):
  _list.sort()
  if len(_list) % 2 == 0:
    n = len(_list) / 2
    m = n - 1
    mid = (_list[n] + _list[m]) / 2
  else:
    n = len(_list) / 2
    mid = (_list[n]) / 2
  
  return mid 
    

Please help me.


#2

Have you taken into account that Python 2 returns an integer from integer division?

let a and b both be integers

c = a / b 

c will be an integer

The numerator in your operation is a sum that may be an odd number.

9 / 2  =>  4

float(9) / 2  =>  4.5

#3

Oh yes, thanks. It will look like this:

mid = (_list[n] + _list[m]) / 2.0

and

mid = (_list[n]) / 2.0

but even with that it still doesn’t work.


#4

No division required. Odd length lists have a single element as the median. Only even length requires averaging the middle two elements.

(n + m) / 2.0

is fine, though it implies that a counting number, 2 is a float.

float(n + m) / 2

treats a counting number as a natural, not a float. A minor point that usually only I ever bring up.

Once we make the move to Python 3, floats are the standard quotient, and integers must be declared.


#5

OK. Thank you. I ran the program on another editor, and the error is:

TypeError: list indices must be integers or slices, not float

But I can’t notice any issue with the indices. Please help.


#6

My code above was only meant as an example, so I hope you only adjusted your earlier code to suit.

Let’s take a closer look at your initial code…

_list.sort()

This is fine if the integrity of the inputs is not a factor. When handed in a list that is not sorted, performing this inplace sort will have a direct effect on the global object if it exists in declared form (not written in the argument as a literal). That may not be the desired outcome, though, so creating a sorted copy is a safer approach that does not affect objects outside of the function.

s = sorted(_list)

We can cache the expressions that are repeated, such as the length and the midpoint.

n = len(s)
m = int(n / 2)

Now we can build two return statements (conditionally for one of them) and be on our way…

if n % 2: return s[m]

return float(s[m - 1] + s[m]) / 2

Above we declare m an integer for the sake of explicitness. In Python 2 it will be an integer, but in Python 3 it will be a float. Casting an INT right there says it all.

The latter return line is for Python 2, since Python 3 will evaluate to a float already. Again, done according to my reasoning as illustrated earlier.


#7

Thank you very much. The part about the sort and sorted function is technical, so I’ll have to read more on both functions then.


#8

Here is an example to go along with your reading…

fullScale = ['do', 're', 'mi', 'fa', 'sol', 'la', 'ti', 'do']
def with_sorted(x):
    scale = sorted(x)
    return scale

print (with_sorted(fullScale))

# -> ['do', 'do', 'fa', 'la', 'mi', 're', 'sol', 'ti']

print (fullScale)

# -> ['do', 're', 'mi', 'fa', 'sol', 'la', 'ti', 'do']

def with_sort(x):
    x.sort()

with_sort(fullScale)
print (fullScale)

# -> ['do', 'do', 'fa', 'la', 'mi', 're', 'sol', 'ti']

See how the global object is directly affected by the latter function?


#9

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.