web-dev-qa-db-ja.com

Python OrderedDictのi番目の要素を選択

辞書をアルファベット順に並べ替えるコードの断片があります。順序付けされたディクショナリでi番目のキーを選択し、対応する値を返す方法はありますか?つまり.

import collections
initial = dict(a=1, b=2, c=2, d=1, e=3)
ordered_dict = collections.OrderedDict(sorted(initial.items(), key=lambda t: t[0]))
print(ordered_dict)

OrderedDict([('a', 1), ('b', 2), ('c', 2), ('d', 1), ('e', 3)])

の機能に沿って機能したい...

select = int(input("Input dictionary index"))
#User inputs 2
#Program looks up the 2nd entry in ordered_dict (c in this case)
#And then returns the value of c (2 in this case)

どうすればこれを達成できますか?ありがとう。

(- ordereddictの項目へのアクセス と同様ですが、キーと値のペアの値のみを出力します。)

19
Pingk

Python 2:

キーにアクセスする場合:

>>> ordered_dict.keys()[2]
'c'

値にアクセスする場合:

>>> ordered_dict.values()[2]
2

Python 3を使用している場合は、KeysViewメソッドによって返されたkeysオブジェクトをリストとしてラップすることで変換できます。

>>> list(ordered_dict.keys())[2]
'c'
>>> list(ordered_dict.values())[2]
2

かわいらしいソリューションではありませんが、機能します。

20
Daniel Lee

itertools.islice は、添字を付けるために中間リストを作成する必要がないため、ここでは効率的です。

from itertools import islice
print(next(islice(ordered_dict.items(), 2, None)))

値だけが必要な場合は、

print ordered_dict[next(islice(ordered_dict, 2, None))]
12
thefourtheye

OrderedDictを使用する必要がありますか、それとも、インデックス付けをサポートするdictのようなタイプが必要ですか?後者の場合、ソートされたdictオブジェクトを検討してください。 SortedDictの一部の実装(キーの並べ替え順序に基づいてペアを並べ替えます)は、高速のn番目のインデックス付けをサポートしています。たとえば、 sortedcontainers プロジェクトには、ランダムアクセスインデックスを使用した SortedDict タイプがあります。

あなたの場合、それは次のようになります:

>>> from sortedcontainers import SortedDict
>>> sorted_dict = SortedDict(a=1, b=2, c=2, d=1, e=3)
>>> print sorted_dict.iloc[2]
'c'

多くのルックアップを行う場合、これは、目的のインデックスに対して繰り返し反復するよりもたくさん速くなります。

6
GrantJ

あなたはこれらの線に沿って何かをすることができます(奇数は順序付けられたdictです):

def get_idx(od, idx):
   from itertools import islice
   idx = (idx + len(od)) % len(od)
   t = islice(od.items(), idx, idx + 1)
   return next(t)

>>>x

OrderedDict([('a', 2), ('b', 3), ('k', 23), ('t', 41), ('q', 23)])

>>>get_idx(x, 1)
('b', 3)
>>>get_idx(x, 2)
('k', 23)
>>>get_idx(x, 4)
('q', 23)
>>>get_idx(x, -1)
('q', 23)
>>>get_idx(x, -2)
('t', 41)
0
Lin Endian

単なる 'ole for ループだけを過小評価しないでください:

from collections import OrderedDict

od=OrderedDict([('a', 1), ('b', 2), ('c', 2), ('d', 1), ('e', 3)])

def ith(od, tgt):
    for i, t in enumerate(od.items()):
        if i==tgt:
            print('element {}\'s key is "{}"'.format(i,t[0]))
            break
    else:
        print('element {} not found'.format(tgt)) 

ith(od, 2)
# element 2's key is "c"
ith(od, 20) 
# element 20 not found

ここでの利点は、目的の要素が見つかるとすぐにループが中断し、見つからない場合は適切な結果が返されることです...

欠点は、相対スライスがサポートされていないことです。

0
dawg