— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 2020.12.9 update — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Simplified bisect_left

def takeClosest(myList, myNumber) :
    if (myNumber >= myList[-1) :return myList[-1]
    elif myNumber <= myList[0] :return myList[0]
    pos = bisect_left(myList, myNumber)   Find the index of the first number in myList that is not less than myNumber
    The insertion point pos can split myList into two parts. All (val < x for val in myList[lo: I]), all(val >= x for val in myList[I :hi])
    before = myList[pos - 1]
    after = myList[pos]
    if after - myNumber < myNumber - before:
       return after
    else:
       return before
Copy the code

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 2020.12.9 update — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

I forgot why I was looking for this

Method 1

a = [1.4.5.7.31.42.112.175.198.465]
b = 35
print(min(a, key=lambda x: abs(x - b)))
Copy the code

The complexity is a bit high, but you don’t need to have an ordered list, just a list with a target value

Returns the index

def closest(mylist, Number) :
    answer = []
    for i in mylist:
        answer.append(abs(Number-i))
    return answer.index(min(answer))
Copy the code

Method 2

from bisect import bisect_left

def takeClosest(myList, myNumber) :
    """ Assumes myList is sorted. Returns closest value to myNumber. If two numbers are equally close, return the smallest number. If number is outside of min or max return False """
    if (myNumber > myList[-1] or myNumber < myList[0) :return False
    pos = bisect_left(myList, myNumber)
    if pos == 0:
            return myList[0]
    if pos == len(myList):
            return myList[-1]
    before = myList[pos - 1]
    after = myList[pos]
    if after - myNumber < myNumber - before:
       return after
    else:
       return before

a = [1.4.5.7.31.42.112.175.198.465]
b = 35
answer = takeClosest(a, b)
print(answer)
Copy the code

Time complexity is low, binary method, but the list is ordered

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 2020.11.4 update — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Methods 3

import numpy as np
def find_nearest(array, value) :
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return array[idx]

array = np.random.random(10)
print(array)
# [0.0443463 0.01646455 0.44072574 0.21144308 0.47655519 0.14408593
# 0.66480614 0.12407934 0.13441338 0.10409808]
value = 0.5
print(find_nearest(array, value))
# 0.47655518571285727
Copy the code

Do not require the list to be ordered, as long as there is a list, there is a target value on the line, can only handle 1 dimensional

Methods 4

import numpy as np
def find_nearest(array,value) :
    idx = np.searchsorted(array, value, side="left")
    if idx > 0 and (idx == len(array) or abs(value - array[idx-1]) < abs(value - array[idx])):
        return array[idx-1]
    else:
        return array[idx]

a = [1.4.5.7.31.42.112.175.198.465]
b = 185
answer = find_nearest(a, b)
print(answer)
Copy the code

This method requires that the list array be ordered, and numpy. Searchsorted can only handle 1-dimensional data because numpy. Searchsorted accepts only 1-dimensional data

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 2020.11.4 update — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —