AbSaintDane
AbSaintDane

Reputation: 77

Python - Looping (Closest to Average)

I'm a beginner to Python and I'm having some trouble. I want to write a function that returns the element of from a user defined list that is closest to the average of the values of that list.

For example, closest_to_average([0, 5, -1, 6, 1]) should return 1 because the average value of those elements is 2.2 and the element in that list which is closest to 2.2 is 1.

By the way, I want to do this using only len(), range(), loops, if-statements, variables and arithmetic (no built in functions).

Here's the code I have so far:

def closest_to_average(xs):
    avg = sum(xs)/len(xs)
    for i in xs:
        diffo = 100
        diff = abs(avg - i)
        if diff < diffo:
            return diff   

So basically, my logic behined this was that, first, the variable average refers to the average of the list. Then each time the loop runs, it will find the difference between i and the average, and if that difference is less than the previous difference, it will keep checking all elements until it finds the i element such that the difference between it and the average is the least.

The problem is I don't know how to set an initial distance! It has to compare the distance between the first i and the average to something. So I set diffo = 100 out of the sake of trying, but I highly doubt that's the solution.

Upvotes: 0

Views: 670

Answers (3)

Richard Kenneth Niescior
Richard Kenneth Niescior

Reputation: 1870

def closest_to_average(xs):
    avg = sum(xs)/len(xs)
    closest = 0
    for i in xs:
        diff = abs(avg - i)
        if diff < abs(avg - closest):
            closest = i
    return closest 

print(closest_to_average([0, 5, -1, 6, 1]))
print(closest_to_average([1, 11474, 1004]))
print(closest_to_average([2, 2, 2, 2, 2]))
print(closest_to_average([2, 1, 0, -9, 9]))

I included some cases for this; does this meet your needs?

I rushed this on my phone; sorry if it isn't fully tested.

Upvotes: 1

Jim Wood
Jim Wood

Reputation: 961

How about this:

def closest_to_average(xs):
    avg = sum(xs)/len(xs)
    min_diff = None
    closest = None
    for i in xs:
        diff = abs(avg - i)
        if min_diff is None or diff < min_diff:
            min_diff = diff
            closest = i
    return closest

Upvotes: 1

Hugh Bothwell
Hugh Bothwell

Reputation: 56674

Well, if you could use min, it becomes

def closest_to_average(lst):
    avg = sum(lst) / len(lst)
    return min(lst, key = lambda x: abs(avg - x))

In your example, setting disto to any arbitrary number is a bad idea, because it could be less than the actual answer. Why not set it to the first item in your list instead? You know that is at least potentially the correct answer.

Upvotes: 2

Related Questions