Median code explanation

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-11 02:28:13

问题


My professor wrote this median function and I don't understand it very well. Can someone please explain the part about i = len(list)/2 and median = avg() and the else statement?

def avg_list(numbers):  
    sum = 0 
    for num in numbers:
        sum += num

    avg = float(sum)/len(numbers)
    print avg

def median(list):            
    list.sort()
    if len(list)%2 == 0:
        #have to take avg of middle two
        i = len(list)/2
        median = avg()
    else:
        #find the middle (remembering that lists start at 0)
        i = len(list)/2
        median = list        
    return median

To add from an example I saw, for even list length:

def median(s):
    i = len(s)
    if not i%2:
        return (s[(i/2)-1]+s[i/2])/2.0
    return s[i/2]

This works very well but I don't understand the last return s[i/2]?

For odd list length:

x = [1,2,5,2,3,763,234,23,1,234,21,3,2134,23,54]
median = sorted(x)[len(x)/2]

Since x has a list length of odd, wouldn't the [len(x)/2] be a floating number index? I'm not getting this all the way? Any explanation better than mine is much appreciated.


回答1:


We're missing some code here, but we can puzzle it out.

The comments here are instructive. When we check:

    if len(list)%2 == 0:

Then we're checking to see if the list is of even length. If a list has an even number of members, then there is no true "middle" element, and so:

    #have to take avg of middle two
        i = len(list)/2
        median = avg()

We assume that the avg() function is going to return the average of the two middle elements. Since you didn't include a definition of an avg function, it's possible that this is really supposed to be an avg_list function taking the middle two elements of the list.

Now, if the list is of odd length, there is a middle element, and so:

    else:
        #find the middle (remembering that lists start at 0)
        i = len(list)/2
        median = list

Now this looks kinda wrong to me too, but my guess is that the intention is that this should read:

median = list[i]

That would be us returning the middle element of the list. Since the list has been sorted, that middle element is the true median of the list.

Hope this helps!




回答2:


Why this is is very wrong, line by line:

def median(list):              # 1

    list.sort()                # 2

        if len(list)%2 == 0:   
        #have to take avg of middle two
            i = len(list)/2    # 3
            median = avg()     # 4
        else:
            #find the middle (remembering that lists start at 0)
            i = len(list)/2    # 5
            median = list      # 6

        return median

#1: It's a bad idea to give your variables the same name as data types, namely list.

#2: list.sort() will modify the list that is being passed. One would expect a getter like median() not to do that.

#4 It calls a function avg() with no arguments, which is completely meaningless, even if such a function was defined.

#3 and #5 are calculated the same way regardless of the if branch taken. Regardless, i is never used.

#6 It sets median to the original list, which makes zero sense.


Here's how I would rewrite this (while maintaining clarity):

def median(alist):

    srtd = sorted(alist) # returns a sorted copy
    mid = len(alist)/2   # remember that integer division truncates

    if len(alist) % 2 == 0:  # take the avg of middle two
        return (srtd[mid-1] + srtd[mid]) / 2.0
    else:
        return srtd[mid]

Also, the avg_list() function (which is not used nor could be used in median()) could be rewritten as:

def avg_list(numbers):  
    return float(sum(numbers))/len(numbers)

sum() is a function that returns the sum of all elements in an iterable.




回答3:


I'm sure it's trying to say, "If the list is of odd size, just take the central element; otherwise take the mean of the central two elements" - but I can't see that that's what the code is actually doing at all.

In particular:

  • It's calling an avg() function (not avg_list, note) but without any arguments
  • It's ignoring the value of i after computing it in the same way in both branches

Are you sure that's the complete code which is meant to work?




回答4:


You can also decide to always return the average of the middle sub-array of the ordered list: For instance return the average of [4,5] out of [1,2,3,4,5,6,7,8], and that of [5] out of [1,2,3,4,5,6,7,8,9].

A python implementation would be:

def median(a):
    ordered = sorted(a)
    length = len(a)
    return float((ordered[length/2] + ordered[-(length+1)/2]))/2


来源:https://stackoverflow.com/questions/7578689/median-code-explanation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!