Mean of integers, ignoring the largest and smallest values The code returns the mean of a list of integers, except ignoring the largest and smallest values in the list. If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value.  Assume that the list is length 3 or more.

For this problem, as part of my learning, I’ve defined my own functions. Please comment on my variable names, docstrings, readability of code etc. and let me know how you would do it.

from typing import Sequence

def find_length(seq: Sequence) -&gt; int:
    """ Return the number of elements in a sequence.

    &gt;&gt;&gt; numbers = [-10, -4, -2, -4, -2, 0]
    &gt;&gt;&gt; find_length(numbers)
    6
    """

    count = 0
    for _ in seq:
        count += 1

    return count


def find_min(numbers: Sequence) -&gt; int:
    """ Return the smallest number in a sequence.

    &gt;&gt;&gt; numbers = [-10, -4, -2, -4, -2, 0]
    &gt;&gt;&gt; find_min(numbers)
    -10
    """    

    min_number = numbers[0]

    for number in numbers:
        if number &lt; min_number:
            min_number = number

    return min_number


def find_max(numbers: Sequence) -&gt; int:
    """ Return the biggest number in a sequence.

    &gt;&gt;&gt; numbers = [-10, -4, -2, -4, -2, 0]
    &gt;&gt;&gt; find_max(numbers)
    0
    """

    max_number = numbers[0]    

    for number in numbers:
        if number &gt; max_number:
            max_number = number

    return max_number


def find_sum(numbers: Sequence) -&gt; int:
    """ Return sum of the numbers in a sequence.

    &gt;&gt;&gt; numbers = [-10, -4, -2, -4, -2, 0]
    &gt;&gt;&gt; find_sum(numbers)
    -22
    """

    total = 0

    for number in numbers:
        total += number

    return total


def find_centered_average(numbers: Sequence) -&gt; int:
    """ Return the centered average of a list of numbers.

    &gt;&gt;&gt; numbers = [-10, -4, -2, -4, -2, 0]
    &gt;&gt;&gt; find_centered_average(numbers)
    -3
    """

    max_number = find_max(numbers)
    min_number = find_min(numbers)    
    total = find_sum(numbers) - max_number - min_number
    centered_average = total // (find_length(numbers) - 2)

    return centered_average


All of that can be accomplished with either:

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


Or,

centered_numbers = sorted(numbers)[1:-1]
sum(centered_numbers) // len(centered_numbers))


There must be a number of other ways to do it.
Well, whenever you want to know which function is better, you should test them.

First, your custom functions are just re-inventing the wheel, so you should only use them if you have to (either because it is mandated or they are actually faster, more secure, more memory-friendly, more whatever).

When running your functions with growing number of numbers, this is what I get:



Here, Input is the length of the numbers list, generated with numpy.random.random_integers(-10, 10, size=n), with \$n\in [10, 10000]\$.

So, for larger lists, the difference between your own function and the sorting function is negligible. The sorting should be \$\mathcal{O}(n\log n)\$, but I don't see why your function seems to show a similar behavior.

The sum/min/max function should be \$\mathcal{O}(3n)\$, so wins for large lists.

For smaller sizes, the two simple implementations perform similarly and your functions slightly slower:



This is for numpy.random.random_integers(-100, 100, size=n), with \$n\in [10, 100]\$.

All measurements were done in Python 2.7.13. I put your last two snippets into functions:

def centered_average_sum(numbers):
    return (sum(numbers) - max(numbers) - min(numbers)) // (len(numbers) - 2)


def centered_average_sort(numbers):
    centered_numbers = sorted(numbers)[1:-1]
    return sum(centered_numbers) // len(centered_numbers)


Note that I fixed a superfluous closing bracket on the second function.