In my code I frequently need to take a subset range of keys+values from a Python OrderedDict
(from collections
package). Slicing doesn't work (throws TypeError: unhashable type
) and the alternative, iterating, is cumbersome:
from collections import OrderedDict
o = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
# want to do:
# x = o[1:3]
# need to do:
x = OrderedDict()
for idx, key in enumerate(o):
if 1 <= idx < 3:
x[key] = o[key]
Is there a better way to get this done?
The ordered dict in the standard library, doesn't provide that functionality. Even though libraries existed for a few years before collections.OrderedDict that have this functionality (and provide essentially a superset of OrderedDict): voidspace odict and ruamel.ordereddict (I am the author of the latter package, which is a reimplementation of odict in C):
In ruamel.ordereddict you can relax the ordered input requirement (AFAIK you cannot ask derivative of dict if its keys are ordered (would be good addition to ruamel.ordereddict to recognise collection.OrderedDicts)):
If you want (or have to) stay within the standard library you can sublass
collections.OrderedDict
's__getitem__
:of course you could use Martijn's or Jimmy's shorter versions to get the actual slice that needs returning:
or if you just want smarten up all existing
OrderedDict
s without subclassing: