Lets say I have the following code:
import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'
Is there a way I can access the items in a numbered manner, like:
d(0) #foo's Output
d(1) #bar's Output
Lets say I have the following code:
import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'
Is there a way I can access the items in a numbered manner, like:
d(0) #foo's Output
d(1) #bar's Output
This community wiki attempts to collect existing answers.
Python 2.7
In python 2, the
keys()
,values()
, anditems()
functions ofOrderedDict
return lists. Usingvalues
as an example, the simplest way isFor large collections where you only care about a single index, you can avoid creating the full list using the generator versions,
iterkeys
,itervalues
anditeritems
:The indexed.py package provides
IndexedOrderedDict
, which is designed for this use case and will be the fastest option.Using itervalues can be considerably faster for large dictionaries with random access:
Python 3.6
Python 3 has the same two basic options (list vs generator), but the dict methods return generators by default.
List method:
Generator method:
Python 3 dictionaries are an order of magnitude faster than python 2 and have similar speedups for using generators.
Here is a special case if you want the first entry (or close to it) in an OrderedDict, without creating a list:
(The first time you say "next()", it really means "first.")
In my informal test in Python 2.7,
iteritems().next()
with a small OrderedDict is only a tiny bit faster thanitems()[0]
. With an OrderedDict of 10,000 entries,iteritems().next()
was about 200 times faster thanitems()[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 iteritems() iterator and step through it to to the position you want }, that could be slower.
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.
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.
IndexedOrderedDict is ~100 times faster in indexing elements at specific position in this specific case.
If its an
OrderedDict()
you can easily access the elements by indexing by getting the tuples of (key,value) pairs as followsNote 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 possibleIt's a new era and with Python 3.6.1 dictionaries now retain their order. These semantics aren't explicit because that would require BDFL approval. But Raymond Hettinger is the next best thing (and funnier) and he makes a pretty strong case that dictionaries will be ordered for a very long time.
So now it's easy to create slices of a dictionary:
Note: Dictonary insertion-order preservation is now official in Python 3.7.