7

我的教授写了这个中值函数,我不太理解。有人可以解释一下关于i = len(list)/2和声明median = 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

4 回答 4

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为 original 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()是一个函数,它返回一个可迭代对象中所有元素的总和。

于 2011-09-28T05:51:47.530 回答
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]

那将是我们返回列表的中间元素。由于列表已排序,因此中间元素是列表的真正中位数。

希望这可以帮助!

于 2011-09-28T05:35:31.170 回答
2

我敢肯定它试图说,“如果列表大小奇数,只取中心元素;否则取中间两个元素的平均值” - 但我看不出那是代码实际在做什么全部。

尤其:

  • 它正在调用一个avg()函数(不是avg_list,注意)但没有任何参数
  • 它忽略了i在两个分支中以相同方式计算后的值

你确定这是完整的代码

于 2011-09-28T05:30:39.237 回答
2

您还可以决定始终返回有序列表的中间子数组的平均值:例如返回 [1,2,3,4,5,6,7,8] 中 [4,5] 的平均值,以及 [1,2,3,4,5,6,7,8,9] 中的 [5]。

python 实现将是:

def median(a):
    ordered = sorted(a)
    length = len(a)
    return float((ordered[length/2] + ordered[-(length+1)/2]))/2
于 2012-06-15T05:27:04.790 回答