1
\$\begingroup\$

I'm learning Python & practising from this site and here is the particular problem at hand:

Return the "centered" average of an array of ints, which we'll say is the mean average of the values, except ignoring the largest and smallest values in the array. If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value. Use int division to produce the final average. You may assume that the array is length 3 or more.

centered_average([1, 2, 3, 4, 100])3
centered_average([1, 1, 5, 5, 10, 8, 7])5
centered_average([-10, -4, -2, -4, -2, 0])-3

My solution is as follows:

def centered_average(nums):
 items = len(nums)
 total = 0
 high = max(nums)
 low = min(nums)
 for num in nums:
 total += num
 aveg = (total -high-low) / (items-2)
 return aveg

The above code works fine. I want to ask more experienced programmers if this could be done in a better manner - or is this solution fine?

asked Sep 23, 2015 at 10:52
\$\endgroup\$
1
  • \$\begingroup\$ I depends what do you mean with better way. Better with regard to beauty, time, long inputs,...? \$\endgroup\$ Commented Sep 23, 2015 at 11:10

4 Answers 4

2
\$\begingroup\$

You can replace your for-loop with

total = sum(nums)

There is also no need in internal variables. Therefore you can write your function in just one line:

def centered_average(nums):
 return (sum(nums) - max(nums) - min(nums)) / (len(nums) - 2) 
answered Sep 23, 2015 at 10:59
\$\endgroup\$
6
  • \$\begingroup\$ @wenzul in this particular case it does, as the problem states that I can assume the array length to be 3 or more \$\endgroup\$ Commented Sep 23, 2015 at 11:15
  • \$\begingroup\$ @wenzul How is "centered" average defined for less than 3 numbers? \$\endgroup\$ Commented Sep 23, 2015 at 11:19
  • \$\begingroup\$ @awkward101 Ok, skipped that. @Alex.S NotImplemented :) \$\endgroup\$ Commented Sep 23, 2015 at 11:19
  • \$\begingroup\$ @wenzul Ok :) BTW it will not work if len(nums) == 2 but WILL work if len(nums) == 1 ;) \$\endgroup\$ Commented Sep 23, 2015 at 11:24
  • \$\begingroup\$ @Alex.S Hm, it depends on how the function will be defined. If you assume that nums[0] is both min and max should we throw it away? We should define a domain to solve that mathematical problem. :) \$\endgroup\$ Commented Sep 23, 2015 at 11:27
4
\$\begingroup\$

This code can be written more concisely in a couple of ways:

You can use the sum function rather than an explicit loop:

(sum(nums) - max(nums) - min(nums)) / (len(nums) - 2)

You could also use sorting and slicing to remove the extreme values, which is more concise but less efficient:

sum(sorted(nums)[1:-1]) / (len(nums) - 2)

The slice notation [1:-1] takes the elements of a list starting with the second element (index 1) and finishing with the last-but-one element (index -1, i.e. indexing from the end of the list rather than the start)

If you are using Python 3.4+ you can use the statistics module, which has a mean function:

from statistics import mean
mean(sorted(nums)[1:-1])
answered Sep 23, 2015 at 11:02
\$\endgroup\$
2
\$\begingroup\$

If you don't care too much about performance:

def centered_average(nums):
 return sum(sorted(nums)[1:-1]) / (len(nums) - 2)

Otherwise look for the other answers.

answered Sep 23, 2015 at 11:01
\$\endgroup\$
2
  • 1
    \$\begingroup\$ For large lists, requesting the max and min separately will be more efficient than sorting and removing the first and last. \$\endgroup\$ Commented Sep 23, 2015 at 11:02
  • \$\begingroup\$ You are right, of course. \$\endgroup\$ Commented Sep 23, 2015 at 11:03
1
\$\begingroup\$

You could just throw away the first and last element in your list:

def centered_average(nums):
 #nums = sorted(nums) # if input is not always sorted
 nums1 = nums[1:-1]
 return sum(nums1) / len(nums1)
answered Sep 23, 2015 at 11:04
\$\endgroup\$
5
  • \$\begingroup\$ This works only on sorted lists. \$\endgroup\$ Commented Sep 23, 2015 at 11:11
  • \$\begingroup\$ @honza_p Please read the source code before downvote. \$\endgroup\$ Commented Sep 23, 2015 at 11:11
  • 1
    \$\begingroup\$ Sorry, I usually automatically skip #'s when reading. \$\endgroup\$ Commented Sep 23, 2015 at 11:12
  • 2
    \$\begingroup\$ @honza_p Are you a human or a machine? :) \$\endgroup\$ Commented Sep 23, 2015 at 11:15
  • \$\begingroup\$ I've just read lots of code \$\endgroup\$ Commented Feb 21, 2022 at 7:08

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.