web-dev-qa-db-ja.com

Python OrderedDict?

私は collections.OrderedDict キーと値のペアのリスト。 i番目のキーが指定された値と一致するようにインデックスiを計算したいと思います。例えば:

food = OrderedDict([('beans',33),('rice',44),('pineapple',55),('chicken',66)])

キーchickenからインデックス3に移動したい、またはキーriceからインデックス1に移動したい。

food.keys().index('rice')

しかしキー名で物事をすばやく検索するOrderedDictの機能を活用する方法はありますか?それ以外の場合はインデックス検索のようですO(log N)ではなくO(N)になり、アイテムがたくさんあります。

独自のインデックスを作成することで、これを手動で実行できると思います。

>>> foodIndex = {k:i for i,k in enumerate(food.keys())}
>>> foodIndex
{'chicken': 3, 'rice': 1, 'beans': 0, 'pineapple': 2}

しかし、私はOrderedDictに何かが組み込まれているのではないかと期待していました。

17
Jason S

基本的にはありません。 OrderedDictは、内部で通常の順序付けられていないdictを使用するだけで、キー名ですばやく検索する機能を備えています。注文情報は、二重リンクリストに個別に保存されます。このため、キーからそのインデックスに直接移動する方法はありません。 OrderedDictの順序は、主に反復で使用できるようにすることを目的としています。キーはそれ自体の順序を「認識」しません。

18
BrenBarn

他の人が指摘しているように、OrderedDictは、どの注文エントリが追加されたかを内部的に記憶する単なる辞書です。ただし、各エントリの残りのデータと一緒に目的のインデックスを保存することで、物事をすばやく検索する機能を活用できます。これが私が意味することです:

from collections import OrderedDict

foods = [('beans', 33), ('rice', 44), ('pineapple', 55), ('chicken', 66)]
food = OrderedDict(((v[0], (v[1], i)) for i, v in enumerate(foods))) # saves i

print(food['rice'][1])  # --> 1
print(food['chicken'][1])  # --> 3
4
martineau

OrderedDictはdictのサブクラスであり、キーを 二重リンクリストを維持する の順序で(および逆の順序で)トラバースする機能があります。したがって、キーのインデックスはわかりません。リンクリストをトラバースして、O(n)時間内にアイテムを見つけることしかできません。

ソースコードを熟読する インデックスがOrderedDictによって維持されていないことを確認するための最も満足のいく方法かもしれません。インデックスがこれまでに使用または取得された場所がないことがわかります。

3
unutbu