3

id(整数)を数値(double)にマップする辞書構造があります。数字は実際にはアイテムの重量です。

指定された重みのIDをフェッチできる関数を作成しています(重みがdictで見つかった場合、それ以外の場合は、次に近い(つまり最も一致した)重みのIDを返します。

これは私がこれまでに持っているものです:

def getBucketIdByValue(bucketed_items_dict, value):
    sorted_keys = sorted(bucketed_items_dict.keys())
    threshold = abs(bucketed_items_dict[sorted_keys[-2]] -bucketed_items_dict[sorted_keys[-1]]) # determine gap size between numbers

    # create a small dict containing likely candidates
    temp = dict([(x - value),x] for x in bucketed_items_dict.values() if abs(x - value) <= threshold)
    print 'DEBUG: Deviations list: ', temp.keys()
    smallest_deviation = min(temp.keys()) if value >= 0 else max(temp.keys()) # Not sure about this ?
    smallest_deviation_key = temp[smallest_deviation]
    print 'DEBUG: found bucketed item key:',smallest_deviation_key
    return smallest_deviation_key

ロジックが実際に正しいかどうかはわかりません(特に、最小の偏差を取得する場合)。いずれにせよ、論理さえ正しければ、これは物事を行うための非常に複雑な方法のように思われます。これを行うためのよりエレガントでパイソン的な方法はありますか?

頭から離れて、もっとpythonic / elegativeな方法は、カスタム関数を関数に渡すようなことをすることだと思いminます-それが可能かどうかはわかりません...

[[アップデート]]

Python2.6.5を実行しています

4

4 に答える 4

4

重量から目標値までの距離でアイテムを並べ替えてみてください。

from operator import itemgetter
distances = ((k, abs(v - value)) for k, v in bucketed_items_dict.items())
return min(distances, key=itemgetter(1))[0]

または、itemgetterの代わりにラムダ関数を使用します。

distances = ((k, abs(v - value)) for k, v in bucketed_items_dict.items())
return min(distances, key=lambda x:x[1])[0]
于 2012-07-01T17:40:05.097 に答える
3
def getBucketIdByValue(bucket, value):
    distances = [( id , abs( number - value ) ) for id , number in bucket.items()]
    swapped = [( distance , id ) for id , distance in distances]
    minimum = min ( swapped )
    return minimum[1]

または要するに:

def getBucketIdByValue(bucket, value):
    return min((abs(number-value),id) for id,number in bucket.items())[1]

この関数は、バケットを使用してID /数値のペアを作成し、次に距離/ IDペアのイテレーターを作成し、その最初の最小ペアを取得して、最後にそのペアのIDを抽出して返します。

距離は、数値と求められる値の差の絶対値として定義されます。

最小値は、距離が最も短いペアとして定義されます。それ以上ある場合は、IDが最小のペアが返されます。

于 2012-07-01T17:45:33.230 に答える
2

ソートされたキーでbisectを使用して、最も近い重みのインデックスを見つけることができます。

import bisect

def bisect_weight(sorted_keys, value):
    index = bisect.bisect(sorted_keys, value)
    # edge cases
    if index == 0: return sorted_keys[0]
    if index == len(sorted_keys): return sorted_keys[index - 1]
    minor_weight = sorted_keys[index - 1]
    greater_weight = sorted_keys[index]

    return minor_weight if abs(minor_weight - value) < abs(greater_weight - value) else greater_weight

このように、2つの重みをチェックして、最適な重みを見つける必要があります。並べ替えと二分探索は、すべての重みを計算して最適な重みを見つけるよりもおそらく高速です。

于 2012-07-01T17:57:13.717 に答える
1

bisectモジュールも検討したいと思います。

于 2012-07-01T17:52:35.163 に答える