There is a list with numbers. How to find the number as close as possible to the middle of the list?
list_nums = [5, 7, 10, 13, 17] In this case, this number is 11, but since it is not there the closest to it is 10.
There is a list with numbers. How to find the number as close as possible to the middle of the list?
list_nums = [5, 7, 10, 13, 17] In this case, this number is 11, but since it is not there the closest to it is 10.
>>> import statistics >>> avg = statistics.mean(list_nums) # среднее >>> min(list_nums, key=lambda num: abs(num - avg)) # приближённое к среднему 10 lambda num: abs(num - avg) is a function that expresses the concept of "close to average" - the smaller this value is, the closer to the average (at zero it coincides with the average). You can give the name of this function:
def distance(a, b): return abs(a - b) If we imagine that the points lie on the line, then the distance returns the Euclidean metric - the length of the segment between the points. That is why the abs() function is used, which returns the absolute value : abs(5 - 11) == abs(17 - 11) == 6 in this case, the numbers 5 and 17 at one distance from the average 11 .
min(list_nums, key=lambda num: distance(num, avg)) min() returns the number from the list_nums list that is closest to avg by the metric defined by distance() .
statistics.mean(L) is more accurate than the naive sum(L)/len(L) formula if you want floating point numbers to support:
>>> list_nums = [1e50, 1, -1e50] * 1000 >>> sum(list_nums) / len(list_nums) 0.0 >>> statistics.mean(list_nums) 0.3333333333333333 statistics.mean() does not work this way, but for example it would be enough: math.fsum(list_nums) / len(list_nums) .
In [58]: avg = sum(list_nums)/len(list_nums) In [59]: min([(x,abs(x-avg)) for x in list_nums], key=lambda x: x[1])[0] Out[59]: 10 Step by step analysis:
In [60]: [(x,abs(x-avg)) for x in list_nums] Out[60]: [(5, 5.4), (7, 3.4000000000000004), (10, 0.40000000000000036), (13, 2.5999999999999996), (17, 6.6)] further we find a tuple with the minimum difference:
In [61]: min([(x,abs(x-avg)) for x in list_nums], key=lambda x: x[1]) Out[61]: (10, 0.40000000000000036) and select the first element of the tuple:
In [62]: min([(x,abs(x-avg)) for x in list_nums], key=lambda x: x[1])[0] Out[62]: 10 here is a very elegant version suggested by @jfs
min(list_nums, key=lambda num: abs(num - avg)) Alternative option:
avg = sum(list_nums)/len(list_nums) x = list_nums[0] for i in list_nums: if abs(i - avg) < abs(x - avg): x = i print(x) min() call: min(list_nums, key=lambda num: abs(num - avg)) . For float sum / len, the formula may be inaccurate. You can use statistics.mean - jfsmin(list_nums, key=lambda num: abs(num - avg)) - very elegant! - MaxUSource: https://ru.stackoverflow.com/questions/692629/
All Articles