Accessing items in an collections.OrderedDict by index
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Orient Looping
--
Chapters
00:00 Accessing Items In An Collections.Ordereddict By Index
00:21 Accepted Answer Score 228
00:54 Answer 2 Score 27
01:27 Answer 3 Score 22
02:16 Answer 4 Score 22
02:57 Thank you
--
Full question
https://stackoverflow.com/questions/1005...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #collections #dictionary #python3x #ordereddictionary
#avk47
ACCEPTED ANSWER
Score 228
If its an OrderedDict() you can easily access the elements by indexing by getting the tuples of (key,value) pairs as follows
>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')
Note for Python 3.X
dict.items would return an iterable dict view object rather than a list. We need to wrap the call onto a list in order to make the indexing possible
>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')
ANSWER 2
Score 27
Do you have to use an OrderedDict or do you specifically want a map-like type that's ordered in some way with fast positional indexing? If the latter, then consider one of Python's many sorted dict types (which orders key-value pairs based on key sort order). Some implementations also support fast indexing. For example, the sortedcontainers project has a SortedDict type for just this purpose.
>>> from sortedcontainers import SortedDict
>>> sd = SortedDict()
>>> sd['foo'] = 'python'
>>> sd['bar'] = 'spam'
>>> print sd.iloc[0] # Note that 'bar' comes before 'foo' in sort order.
'bar'
>>> # If you want the value, then simple do a key lookup:
>>> print sd[sd.iloc[1]]
'python'
ANSWER 3
Score 22
Here is a special case if you want the first entry (or close to it) in an OrderedDict, without creating a list. (This has been updated to Python 3):
>>> from collections import OrderedDict
>>> 
>>> d = OrderedDict()
>>> d["foo"] = "one"
>>> d["bar"] = "two"
>>> d["baz"] = "three"
>>> next(iter(d.items()))
('foo', 'one')
>>> next(iter(d.values()))
'one'
(The first time you say "next()", it really means "first.")
In my informal test, next(iter(d.items())) with a small OrderedDict is only a tiny bit faster than items()[0].  With an OrderedDict of 10,000 entries, next(iter(d.items())) was about 200 times faster than items()[0]. 
BUT if you save the items() list once and then use the list a lot, that could be faster. Or if you repeatedly { create an items() iterator and step through it to to the position you want }, that could be slower.
ANSWER 4
Score 22
It is dramatically more efficient to use IndexedOrderedDict from the indexed package.
Following Niklas's comment, I have done a benchmark on OrderedDict and IndexedOrderedDict with 1000 entries.
In [1]: from numpy import *
In [2]: from indexed import IndexedOrderedDict
In [3]: id=IndexedOrderedDict(zip(arange(1000),random.random(1000)))
In [4]: timeit id.keys()[56]
1000000 loops, best of 3: 969 ns per loop
In [8]: from collections import OrderedDict
In [9]: od=OrderedDict(zip(arange(1000),random.random(1000)))
In [10]: timeit od.keys()[56]
10000 loops, best of 3: 104 µs per loop
IndexedOrderedDict is ~100 times faster in indexing elements at specific position in this specific case.
Other solutions listed require an extra step.  IndexedOrderedDict is a drop-in replacement for OrderedDict, except it's indexable.