user308827
user308827

Reputation: 22001

Find the closest elements above and below a given number

myArr = array([4,1,88,44,3])
myNumber = 25
FindClosest(myArr, myNumber)
...
4, 44

Is there any way to find the closest 2 numbers in a list to a given number such that one of them is higher and the other lower?

I can find the closest number by:

min(myArr.tolist(), key=lambda x:abs(x-myNumber))

Upvotes: 23

Views: 29973

Answers (4)

levi
levi

Reputation: 22697

above = min([i for i in myArr if myNumber < i])
below = max([i for i in myArr if myNumber > i])

Also, the correct answer is 44, 4 not 44, 88

Upvotes: 5

Sourav
Sourav

Reputation: 504

I have an answer to find the 2 closest numbers to the input value, please see the program below :-

from collections import OrderedDict


def find_closer():
    a = [9, 19, 87, 43, 10]
    b = int(input("Enter number :"))
    # diff_list = []
    diff_dict = OrderedDict()
    if b in a:
        b = input("Number already exists, please enter another number ")
    else:
        for x in a:
            diff = x - b
            if diff < 0:
                # diff_list.append(diff*(-1))
                diff_dict[x] = diff*(-1)
            else:
                # diff_list.append(diff)
                diff_dict[x] = diff
    print("diff_dict", diff_dict)
    # print(diff_dict[9])
    sort_dict_keys = sorted(diff_dict.keys())
    print(sort_dict_keys)
    closer_less = 0
    closer_more = 0
    for closer in sort_dict_keys:
        if closer < b:
            closer_less = closer
        else:
            closer_more = closer
            break
    print("closer less =", closer_less, "and closer more =", closer_more)


find_closer()

this a pure python program. Hope it helps !!

Upvotes: 0

wim
wim

Reputation: 363123

Sorting is not necessary, and makes this time complexity O(n logn) when it should be just O(n).

I believe this is what you're looking for, taking advantage of numpy array indexing:

>>> # the smallest element of myArr greater than myNumber
>>> myArr[myArr > myNumber].min()  
44

>>> # the largest element of myArr less than myNumber
>>> myArr[myArr < myNumber].max()
4

Upvotes: 50

kjschiroo
kjschiroo

Reputation: 530

upper = min([ i for i in myArr.tolist() if i >= myNumber], key=lambda x:abs(x-myNumber))
lower = min([ i for i in myArr.tolist() if i < myNumber], key=lambda x:abs(x-myNumber))

Upvotes: 5

Related Questions