Reputation:
i'm trying do order a python dict and i'm trying to find the most pythonic way to do it. Here is what the dict looks like:
{
u'key1': {'a': 'name', 'number': 282},
u'key2': {'a': 'name2','number': 1421},
u'key3': {'a': 'name3', 'number': 95},
}
How can i order this dict to this:
{
u'key2': {'a': 'name2','number': 1421},
u'key1': {'a': 'name', 'number': 282},
u'key3': {'a': 'name3', 'number': 95},
}
Ordering by the number key in the intern dict? Thanks for helping!
Upvotes: 0
Views: 3531
Reputation: 114025
Dictionaries are unordered. The values they hold are accessed by the keys with which those values are associated.
Thus, if you wanted the dictionary {'a': 'name', 'number': 282}
, you would access it by calling myDict[u'key1']
.
It is very rarely the case that ordering the keys in a dict
is a required/useful feature.
However, for whatever reason, if you still want to order the dict somehow, you could look into using a collections.OrderedDict
, which will preserve the order in which you insert key,value pairs
If you want a list of those inner dict
s ordered by the value associated with their 'number'
keys, then this will do it:
myList = sorted(myDict.values(), key=lambda d:d['number'])
Hope this helps
Upvotes: 1
Reputation: 365905
If you want a dict that maintains a sorted order, you need a different data structure. If you search PyPI you'll find a variety of options.
Some of them are built on top of data structures designed for this kind of thing (red-black trees, B-trees, skip lists), so they'll do everything pretty quickly. Others work by just re-sorting every time you modify them (or do a smarter variation—re-sorting every time you access them after one or more modification).
I don't want to recommend one in particular and stop you from reading over a few of them, so I'll just show how to do it with the first one that comes back in the search, sorteddict
, which I've never used:
sd = sorteddict.sorteddict({
u'key1': {'a': 'name', 'number': 282},
u'key2': {'a': 'name2','number': 1421},
u'key3': {'a': 'name3', 'number': 95},
}, key=operator.itemgetter('number'))
However, if you're just building the dict all at once and never modifying it, it's easier (and probably faster) to use an OrderedDict
, as explained in inspectorG4dget's answer. Just put the keys and values in sorted order first. Or even use sorted
to do it for you:
od = collections.OrderedDict(sorted(d.items(), key=lambda item: item[1]['number']))
If you want to do this manually, you can do it by using an "index list": a list (or OrderedDict
or sortedlist
or sorteddict
) of keys that you build or maintain in order, and use to find the key to look up. But there's really no good reason to do this unless you need to have multiple ways of indexing the same mapping (or to learn how OrderedDict
works under the covers—but for that, start by reading the Ordered Dictionary for Py2.4 recipe linked from the docs).
Upvotes: 3