Sie können dies tun, indem man zuerst die Liste sortieren und dann binäre Suche verwenden:
from bisect import bisect_left
class CustomRound:
def __init__(self,iterable):
self.data = sorted(iterable)
def __call__(self,x):
data = self.data
ndata = len(data)
idx = bisect_left(data,x)
if idx <= 0:
return data[0]
elif idx >= ndata:
return data[ndata-1]
x0 = data[idx-1]
x1 = data[idx]
if abs(x-x0) < abs(x-x1):
return x0
return x1
Sie können als konstruieren Ihre CustomRound
wie:
values = [1,3.12,4]
custom_round = CustomRound(values)
und rufen Sie einfach an:
>>> custom_round(0)
1
>>> custom_round(0.5)
1
>>> custom_round(1.5)
1
>>> custom_round(2.5)
3.12
>>> custom_round(3.12)
3.12
>>> custom_round(3.9)
4
>>> custom_round(4.1)
4
>>> custom_round(4.99)
4
Dieser Ansatz wird für die Rundung in O (log n) arbeiten und O (n log n) für den Bau. Sie werden also etwas zusätzliche Zeit investieren, um das custom_round
zu konstruieren, aber wenn Sie es oft anrufen, wird es sich schließlich in runden individuellen Zahlen auszahlen.
Werfen Sie einen Blick [hier] (http://stackoverflow.com/questions/12141150/from-list-of-integers-get-number-closest-to-a-given-value) – nlsdfnbch
Excatly, was ich brauchte – bluesummers