I am assuming that you want to keep this function general, or that you are intentionally re-inventing the wheel (otherwise you would likely want to use numpy's median function, or the statistics median function for python 3.4+).
First:
def median(lst):
I don't see any length checking on the list. If the user supplies an empty list, I would expect a meaningful exception.
Alternatively, the function could provide an optional default value (similar to the built-in sum
), but this would be less intuitive to me.
Second:
nl = []
nl = sorted(lst)
e = int(len(nl))
Initializing n1 is unnecessary here. The result of len
also does not need to be converted - the result is always an int. The variable names should also be more descriptive to explain their contents or intent.
Third:
if e % 2 != 0: # True if odd # of #'s
ind = int(((e / 2.0) - 0.5)) # index of the median
c = nl[ind]
print c
In any language, I am always very careful when doing rounding and/or floating point operations. The correctness of this looks questionable to me (especially without comments). Luckily, python has integer division (//
), which rounds down and makes simpler operations like this one clearer.
This could should also return the value, rather than printing it, in order to keep the IO portions separate from the calculations. Separating the print
will make it easier to maintain and re-use the function.
Fourth:
else: # even # of #'s
ind_left = int(e / 2.0) - 1 # index left of median
ind_right = int(e / 2.0) # index right of median
z = (nl[ind_left] + nl[ind_right]) / 2.0
print z
An obvious optimization here is to avoid recalculating the value in ind_left
to get ind_right
(ind_left == ind_right - 1
).
Taking all of these suggestions will result in code that is something like this:
def median(lst):
if not lst:
raise ValueError('Cannot find median of an empty list')
sorted_items = sorted(lst)
# Determine if even number of items (True) or odd (False)
is_even = (len(sorted_items) % 2) == 0
median_index_l = len(sorted_items) // 2
if is_even:
# Even number of items -- median is average of two middle items
return (sorted_items[median_index_l] + sorted_items[median_index_l + 1]) / 2.0
else:
# Odd number of items -- median is middle item
return sorted_items[median_index_l]