2012-03-26 20 views
5

私は事前に定義された整数のPythonのリストを持っている:Pythonの:リスト内の次の定義済みの整数にラウンド

intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000] 

私は切り捨てと、リスト内の次に低い/高い値にまでする必要があります。たとえば、数字が8000の場合、結果は[7500, 10000]になります。 42000の場合は[40000, 50000]である必要があります。私はそれを行う簡単な方法があるかどうか疑問に思っています。

私の考えは、2つのループを持つ関数を作成することです。リスト内で値が-1になるまで値を減少させる関数と、より高い一致を見つけるまで値を1増加させる関数です。これはうまくいくかもしれませんが、おそらくもっと良い解決策がありますか?

答えて

15

これはbisect.bisect_right()とbisect.bisect_left()に最適です。ここで

は、あなたが拡大することができたため、いくつかのサンプルコードです:

import bisect 

def get_interval(x): 
    intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000] 
    i = bisect.bisect_right(intvals,x) 
    return intvals[i-1:i+1] 

print get_interval(5500) 

""" 
>>> 
[5000, 7500] 
""" 

それはバイナリ検索を使用すると、この技術は高速です(代わりにNルックアップのようlogN個)

+0

これは素晴らしいことです。 –

+1

特に、(get_interval(5)は定義されていますか)エッジケースを扱うコードが必要です。 –

+0

あなたの高速応答に感謝します。正確に私が必要なもの! – Daniel

2

bisectこのように検索するために構築されています。

>>> intvals[bisect.bisect(intvals, 8000)] 
10000 
>>> intvals[bisect.bisect(intvals, 42000)] 
50000 
5

あなたはbisectモジュールを使用することができます。境界ケースのニーズを満たすために例を微調整する必要があるかもしれません。

>>> import bisect 
>>> def RoundUpDown(rangeList,num): 
    beg = bisect.bisect_right(rangeList,num) 
    if rangeList[beg-1] == num: #Handle Perfect Hit Edge Case 
     return [num,num] 
    elif not beg: #Left Edge Case 
     return [None,rangeList[0]] 
    elif beg == len(rangeList): #Right Edge Case 
     return [rangeList[-1],None] 
    else: 
     return rangeList[beg-1:beg+1] 


>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],41000) 
[40000, 50000] 
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],5000) 
[5000, 5000] 
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],500) 
[None, 5000] 
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],50000) 
[50000, 50000] 
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],51000) 
[50000, None] 
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],7500) 
[7500, 7500] 
>>> 
0

maxintに 'minDiff' intを、-1に 'minIndex'を設定します。リストを反復し、インデックス付きリスト値とターゲットの間の差の絶対値を計算します。この値がminDiffより小さい場合はminDiffにロードし、minIndexにインデックスを格納します。値がminDiffより大きい場合は、minIndexを返します。注 - リストがソートされていると仮定します。リストがソートされていない場合は、リスト全体を反復して、最小の違いが見つかったかどうかを確認する必要があります。

0

あなたは間隔が大きすぎるではありませんしていて、メモリ消費量についてあまり心配していない場合は、次の解決策が速くなります:私は何get_interval(心配しないで持って

intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000] 

pairs = zip(intvals,intvals[1:]) 
d = {} 
for start,end in pairs: 
    for i in range(start,end+1): 
     d[i] = (start,end) 

def get_interval(i): 
    if i in d: 
     return d[i] 
    else: 
     return -1 

print get_interval(5500) 

""" 
>>> 
(5000, 7500) 
""" 

ノート7500)は返さなければなりませんが(7500は2つの間隔にありますが)、それをあなたが望むものに修正することができます。

関連する問題