2017-07-17 15 views
1

お役立ち情報のソートされたリストを検索:見さまざまなデータ型のリストをソートする方法についてはPythonの:タプル

How to sort (list/tuple) of lists/tuples?

...と実行方法については、ソートされたリストのバイナリ検索を参照してください。Binary search (bisection) in Python

私の質問:

バイナリ検索(または別のログ(n)検索アルゴリズム)をデータ型の内部コンポーネントであるデータ型のリストにきれいに適用するにはどうすればよいですか?簡単な質問を保つために、私たちは、一例として、タプルのリストを使用することができます。

x = [("a", 1), ("b",2), ("c",3)] 
binary_search(x, "b") # search for "b", should return 1 
# note how we are NOT searching for ("b",2) yet we want ("b",2) returned anyways 

をさらに簡素化するために:我々は唯一の例(「B」であれば、複数のない、単一の検索結果を返す必要があり、2 )と( "b"、3)の両方が存在していた。いっそ

はどのように我々は、上記の操作を実行するには、次の簡単なコードを変更することができますか?

from bisect import bisect_left 

def binary_search(a, x, lo=0, hi=None): # can't use a to specify default for hi 
    hi = hi if hi is not None else len(a) # hi defaults to len(a) 
    pos = bisect_left(a, x, lo, hi) # find insertion position 
    return (pos if pos != hi and a[pos] == x else -1) # don't walk off the end 

ご注意:私は完全なアルゴリズム自体を探していませんをしています。むしろ、Pythonの標準(ish)ライブラリやPythonの他の機能のアプリケーションを探していますので、いつでも任意のデータ型のソート済みリストを簡単に検索できます。

おかげ

答えて

1

は、不等長のタプルとどのように辞書式順序のお得な情報を利用してください:

# bisect_right would also work 
index = bisect.bisect_left(x, ('b',)) 

時々bisectにカスタムシーケンスの種類を供給することが便利であり:

class KeyList(object): 
    # bisect doesn't accept a key function, so we build the key into our sequence. 
    def __init__(self, l, key): 
     self.l = l 
     self.key = key 
    def __len__(self): 
     return len(self.l) 
    def __getitem__(self, index): 
     return self.key(self.l[index]) 

import operator 
# bisect_right would *not* work for this one. 
index = bisect.bisect_left(KeyList(x, operator.itemgetter(0)), 'b') 
+0

修飾に単純なバイナリサーチアルゴリズムのライン5: POS = bisect_leftは(、(X)、HI、LO)#の検索挿入位置 ...所望の効果を有し、返しありません-1が見つかりません。 –

+0

@StephenLasky:インデックスの検索方法を紹介しています。あなたの 'binary_search'関数には他の問題があります。例えば、 'x 'と' a [pos] 'を直接比較しているので、正しいエントリが見つかったとは理解できません。 – user2357112

+0

私の間違いは、すべてが完璧に動作します。好奇心から:あなたはN番目の位置を検索するために上記のプロパティをどのように変更できますか? –

1

タプルのリストをDICTに変換するのはどうですか?

>>> d = dict([("a", 1), ("b",2), ("c",3)]) 
>>> d['b'] # 2 
+0

ここでの問題は、私が大量のリスト(> 1,000,000)を扱っていることです。この種の操作は単純に遅すぎるでしょう。私はあなたの応答に感謝します。 –