Function to trim a list and calculate mean of remaining numbers

Question:

I need a function that takes a list of numbers as the input and an optional integer keyword argument trim (that takes on values of 0 or larger).

  1. I want to remove the largest and smallest numbers from the list
    and
  2. Return the mean of the numbers left.

However, I keep getting errors. I am a beginner and have no clue how to fix it.

Here is what I have tried:

def trimmed_mean (lst, trim):
    trimmed_mean.sort()
    if trimmed_mean.remove(max) and trimmed_mean.remove(min):
        return trimmed_mean 
    else: 
        return None

Could someone please help me find my mistake, please? Thanks!

Asked By: Alexandra Barraza

||

Answers:

You have a few errors here.

In your first line, you have a space between the name of your function trimmed_mean and its parameters. It should read:
def trimmed_mean(lst, trim):

Additionally, your actual function logic doesn’t make much sense. Instead, it should read:

lst.remove(max(lst))
lst.remove(min(lst))
return sum(lst)/len(lst)

This will return what you want, though with a dummy parameter trim that doesn’t do anything unless I misunderstood your intention.

Answered By: Jacob Ivanov

First, you should call the list methods on lst, not the function name. Second, min() and max() are built-in functions, and require an iterable as parameter. However, you wouldn’t need them since your list is already sorted and has the minimal and maximal values at each end:

def trimmed_mean(lst, trim):
    if len(lst) < 3:          # guard clause if trimmed list would be empty
        return None
    lst = sorted(lst)[1:-1]   # sort list and splice from second index to second-to-last index
    return sum(lst)/len(lst)  # calculate and return mean

Good to mention: lst.sort() sorts the list in place and doesn’t return anything. sorted(lst) returns the sorted list and doesn’t affect the original.

Without sorting, you can use the min() and max() functions like so:

def trimmed_mean(lst, trim):
    if len(lst) < 3:   # guard clause if trimmed list would be empty
        return None
    lst.remove(min(lst))
    lst.remove(max(lst))
    return sum(lst)/len(lst)

Finally, if the trim parameter indicates the number of minimal and maximal values to be trimmed, I would use this function:

def trimmed_mean(lst, trim):
    if len(lst) < (trim*2)+1:       # guard clause if trimmed list would be empty
        return None
    lst = sorted(lst)[trim:-trim]   # sort list and splice from second index to second-to-last index
    return sum(lst)/len(lst)        # calculate and return mean

And analogously for the min(), max() solution:

def trimmed_mean(lst, trim):
    if len(lst) < (trim*2)+1:   # guard clause if trimmed list would be empty
        return None
    for _ in range(trim):
        lst.remove(min(lst))
        lst.remove(max(lst))
    return sum(lst)/len(lst)
Answered By: B Remmelzwaal

You can make a correction on your code by taking lst in place of trimmed_mean as it is a function name not the list itself, and as trim is an optional parameter you can pass like =0 to set 0 as default, please find the modified code:

def trimmed_mean (lst, trim=0):
    lst.sort()
    if len(lst)<3: return 0
    return sum(lst[1:-1])/(len(lst)-2)
Answered By: Sakshi Sharma

You can adjust the calculation of the mean without removing the highest and lowest value.

If your list has N numbers, the adjusted mean will be

( (∑ numbers) – minimum – maximum) / (N-2)

Assuming the list has 3 or more items, you only need to find the maximum and minimum values:

minimum = min(lst)
maximum = max(lst)
mean    = ( sum(lst) - minimum - maximum ) / (len(lst) - 2)

Trimming the list (your second parameter) is somewhat unclear to me but if the purpose is to only compute the mean of numbers that are smaller than this value, you can filter the list using a list comprehension before performing the calculations:

lst = [n for n in lst if n<trim] 
Answered By: Alain T.
from statistics import mean #import a package

list_of_nums = list() #creating a list

running = True #our key for stopping or repeating loop

while running == True: #while we let the loop repeat
  client_input = float(input("Enter your number: ")) #getting a number
  list_of_nums.append(client_input) #adding the number to the list
  print(f"your current list ==> {list_of_nums}") #showing new list
  ask = input("do you want to continue? (any button,n)") #asking for continue
  ask = ask.lower() #make the answer lowercase for preventing from bug
  if ask == "n": #if user doesn't want to continue
    max_num = max(list_of_nums) #getting Maximum value
    min_num = min(list_of_nums) #getting Minimum value
    list_of_nums.remove(max_num) #removing maximum value of the list
    list_of_nums.remove(min_num) #removing minimum value of the list
    list_of_nums.sort() #sorting list
    print(f"{max_num} and {min_num} removed from the list as maximum and minimum values.nYour new list is {list_of_nums}nMean of the list is {mean(list_of_nums)}") #print mean of the list and other info.
    running = False #preventing from repeating

this is what i wrote that contains removing maximum and minimum value and mean of last numbers.

Answered By: Amir Ali
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.