中位数代码解释

7 投票
4 回答
23301 浏览
提问于 2025-04-17 03:14

我的教授写了这个中位数函数,我不是很理解。有人能帮我解释一下 i = len(list)/2median = avg() 还有 else 语句的部分吗?

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

为了举个例子,假设列表长度是偶数:

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

这个方法很好用,但我不明白最后的 return s[i/2] 是什么意思?

对于列表长度是奇数的情况:

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

因为 x 的列表长度是奇数,难道 [len(x)/2] 不是一个小数索引吗?我还是不太明白这个?如果有人能给我更好的解释,我会非常感激。

4 个回答

2

我觉得这段话想表达的是:“如果列表的长度是奇数,就取中间那个元素;如果是偶数,就取中间两个元素的平均值。”不过我看不出代码实际上是怎么做到的。

具体来说:

  • 它调用了一个叫 avg() 的函数(注意不是 avg_list),但没有传入任何参数
  • 在两个分支中计算出的 i 的值被忽略了

你确定这就是完整的代码,应该是这样工作的吗?

12

为什么这个代码有很多问题,逐行解释如下:

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: 给变量起和数据类型一样的名字,比如 list,这是个坏主意。

#2: list.sort() 会直接修改传入的列表。我们通常希望像 median() 这样的获取值的函数不会这样做。

#4: 这里调用了一个没有参数的函数 avg(),这完全没有意义,即使这个函数是定义过的。

#3#5 的计算方式是一样的,不管走的是哪个 if 分支。而且,i 这个变量根本没有被用到。

#6: 这里把 median 设置成了原始的 list,这毫无意义。


这是我会重新写的代码(保持清晰):

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]

另外,avg_list() 这个函数(在 median() 中没有被使用,也无法使用)可以改写为:

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

sum() 是一个函数,可以返回一个可迭代对象中所有元素的总和。

5

这里缺少一些代码,不过我们可以推测一下。

这里的注释很有帮助。当我们检查:

    if len(list)%2 == 0:

那么我们就是在检查这个列表的长度是否是偶数。如果一个列表的成员数量是偶数,那么就没有真正的“中间”元素,因此:

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

我们假设 avg() 函数会返回两个中间元素的平均值。因为你没有提供 avg 函数的定义,所以有可能这个函数实际上应该是 avg_list,专门用来处理列表中的中间两个元素。

现在,如果列表的长度是奇数,就会有一个中间元素,因此:

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

我觉得这部分看起来也有点不对,但我猜测这里的意思应该是:

median = list[i]

这就是我们返回列表中间元素的意思。因为列表已经被排序,所以这个中间元素就是列表的真正中位数。

希望这能帮到你!

撰写回答