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.
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.
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!
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 (notavg_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?
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
精彩评论