Median; having sort issue.....I think


#1



https://www.codecademy.com/en/courses/python-intermediate-en-rCQKw/2/5?curriculum_id=4f89dab3d788890003000096#

Oops, try again. median([4, 5, 5, 4]) returned 5.0 instead of 4.5

I am expecting to get a median of 4.5. I am getting 5, the reason I think is that I am using .sort() improperly but I can't figure it out. Please Help and give advice. Thanks


def median(lst):
    lst.sort()
    index_odd = (len(lst) + 1)/2
    index_even_l =  (len(lst)/2) 
    index_even_r = (len(lst)/2) +1 
    for numbers in lst:
        if len(lst) % 3 == 0:
            return lst[index_odd]
        else:
            if len(lst) % 2 == 0:
                return ((lst[index_even_l]) + (lst[index_even_r]))/2.0
    return numbers


#2

Hm... Let's shorten your code first:

My code:

def median(l):
    lng = len(l)
    l = sorted(l)
    if lng % 2 == 0:
        return (l[int(lng)/2-1]+l[int(lng)/2])/2.0
    else:
        return l[int(lng)/2]

You won't need that for loop :slight_smile:


#3

I'll try to explain some of the things that look odd within here, hopefully that might give some hints.
Hopefully I don't misinterpret anything!

        if len(lst) % 3 == 0:
            return lst[index_odd]
        else:
            if len(lst) % 2 == 0:
                return ((lst[index_even_l]) + (lst[index_even_r]))/2.0
  1. " if len(lst) % 3 == 0 " odd numbers won't always be equal to 0 when % by 3. for example this code would skip this if statement if len(lst) was equal to 11.
  2. in this code block you have two "if"s and one within an "else" this could be shortened down to one if and one else.

For example:

 if len(lst) % 2 == 0:
     return ((lst[index_even_l]) + (lst[index_even_r]))/2.0
 else:
     return lst[index_odd]```

would solve both these problems. as "(even_number) % 2 == 0" will always be true which then activates the if statement when the len(lst) is even, and since "else:" doesn't have a condition, everything other than when len(lst) == even will pass through else, and as there is only odd and even, only odd will pass through.

if you need to have two conditions it's better to have elif (else if) rather than if within else.

I'll put my solution to the problem below and explain it, and hopefully it helps.
Raw:

def median(taken_list):
    taken_list = sorted(taken_list)
    mid_point = (len(taken_list) / 2)
    if len(taken_list) % 2 == 0:
        return ((taken_list[mid_point - 1]) + (taken_list[mid_point])) / (2.0)
    else:
        return taken_list[mid_point]

Explained:

def median(taken_list):
     taken_list = sorted(taken_list) #sorts the list
    mid_point = (len(taken_list) / 2) #finds the mid point of the list
       if len(taken_list) % 2 == 0: #finds "if" there's an even length of list, and if so;
           return ((taken_list[mid_point - 1]) + (taken_list[mid_point])) / (2.0) #returns the equation. (see reasoning below)
       else:
           return taken_list[mid_point] # if not even length of list (else) return the the value of the taken list at the index [mid_point]
Reason for the "even equation" ;
# 1. ( (1 down from midde) + (1 up from middle) ) / 2
# 2. list start at index 0, and length counts from 1, you don't need to +1 the second "(taken_list[mid_point])"

#4

Makes a better explanation than mine. Great job. :slight_smile:


#5

Thanks for the great responses!! I can't believe I didn't realize how off my 'if' statement was about finding odd values. I still am a little confused how you are calculating the median for you even values. Whatever 'int' value is inside the [ ] is considered to be starting from an index of zero? I think this is where I am getting confused is between the length of the list which starts at 1 and the index which starts at zero.


#6

Another question. How would does this treat a 'float'? for instance if you have a list with a length of 5, your midpoint would end up being 2.5 which can't be interpreted as an index. So is the value rounded down to a whole number? This seems to be what's occurring. Also had to add an 'elif' statement for cases where the list is a single value.


#7

what I am interpreting is how would 2.5 be treated as a float. Remember the float function will take the number (remember not integer!) and round down. So your question's answer would be yes. It would take 2 as the midpoint.:grin:

~Candy


#8

def median(lst):
    l = lst
            
    l.sort()
    if len(l) == 1:
        return l[0]
        
    elif len(l) == 2:
        return (l[0] + l[1]) / 2.0
        
    elif len(l) % 2 != 0:
        return l[(len(l) - 1) / 2]
        
    else:
        a = l[len(l) / 2]
        b = l[(len(l) / 2) - 1]
        return (a + b) / 2.0

New work :slight_smile:


#9

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