Python select ith element in OrderedDict

只愿长相守 提交于 2019-12-04 22:37:18

In Python 2:

If you want to access the key:

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

If want to access the value:

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

If you're using Python 3, you can convert the KeysView object returned by the keys method by wrapping it as a list:

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

Not the prettiest solution, but it works.

Using itertools.islice is efficient here, because we don't have to create any intermediate lists, for the sake of subscripting.

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

If you want just the value, you can do

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

Do you have to use an OrderedDict or do you just want a dict-like type that supports indexing? If the latter, then consider a sorted dict object. Some implementations of SortedDict (which orders pairs based on the key sort order) support fast n-th indexing. For example, the sortedcontainers project has a SortedDict type with random-access indexing.

In your case it would look something like:

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

If you do a lot of lookups, this will be a lot faster than repeatedly iterating to the desired index.

Don't underestimate just a plain 'ole for loop:

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

The advantage here is that the loop will break as soon as the desired element is found and returns a sensible result if not found...

The disadvantage is that relative slices are not supported.

You could do something along these lines (od is the ordered 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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!