Dictionaries can't be sorted -- a mapping has no ordering! -- so, when you feel the need to sort one, you no doubt want to sort its keys (in a separate list). Sorting (key,value) pairs (items) is simplest, but not fastest.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # (IMHO) the simplest approach:
def sortedDictValues1(adict):
items = adict.items()
items.sort()
return [value for key, value in items]
# an alternative implementation, which
# happens to run a bit faster for large
# dictionaries on my machine:
def sortedDictValues2(adict):
keys = adict.keys()
keys.sort()
return [dict[key] for key in keys]
# a further slight speed-up on my box
# is to map a bound-method:
def sortedDictValues3(adict):
keys = adict.keys()
keys.sort()
return map(adict.get, keys)
|
The concept of 'sort' applies only to a collection which has _order_ -- a sequence; a mapping (e.g. a dictionary) has NO order, thus it cannot be sorted. Still, its keys can be extracted as a list, which can then be sorted. The example functions return the values in order of sorted key, which just happens to be the single most frequent actual need corresponding to user questions such as "how do I sort a dictionary":-)
The implementation choices are interesting. Since we are sorting key-value pairs by the key field, then returning the list of value fields, it seems clearest (conceptually simplest) to architect the solution as in the first example: .items, .sort, then a list comprehension to pick the value fields.
However (at least on my machine) this turns out not to be fastest: extracting just the keys, sorting them, then accessing the dictionary for each key in the resulting list comprehension, as in the second example, appears to be speedier.
Furthermore, it is subject to a further, obvious optimization: from the dictionary we can extract just once the bound-method adict.get, which will map each key to the corresponding value, then use builtin function map to build the list obtained by applying this callable to each item in the sorted list of keys. This does indeed provide a further speed-up (again, on my machine).
Simplicity is a great virtue, but the second and third examples aren't really more complicated (or complex) than the first -- just, perhaps, a little bit subtler. They're probably worth using to 'sort' any dictionary, even though their performance advantages are really only measurable for large ones -- because uniformity of idiom is also an important programming virtue!
re: dictionary 'sort' hello,
How would you sort a dictionary if the keys are not numbers or strings but tuples
e.g. {(0, 1): 2, (0, 2): 3, ...}
Sorting a list of tuples/lists... Where Alist = [(3, 4), (2, 3), (1, 2)], Alist.sort() yields [(1, 2), (2, 3), (3, 4)]. I love this language!
Sorting dictionary by values. Here's some code to sort the keys of a dictionary by their associated values.
newbie sort. I just came here straight from diveintopython section on dictionaries... Is this any different or simmilar to which solution?
typo. def sortedDictValues2(adict): keys = adict.keys() keys.sort() return [adict[key] for key in keys]
List comprehensions and the 2.4 sorted() function.
sort_dict. This would sort the dictionary by the field (numeric column) you supply and return the result in form of a list.
def sort_dict(dictionary, field): tmp_list = [] for key, value in dictionary.items(): tmp_list.append([key, value]) tmp_list.sort(key=lambda x:x[field]) return tmp_list
why not pass in a function to sort ??????? strange people, making fast things slow, easy things hard
sorting by value ...
... return cmp(x[1],y[1])
...
[('drie', 3), ('vier', 4), ('een', 1), ('twee', 2)]
[('een', 1), ('twee', 2), ('drie', 3), ('vier', 4)]
[('drie', 3), ('een', 1), ('twee', 2), ('vier', 4)]
of course reverse sorting would be
... return cmp(y[1],x[1])
...
[('vier', 4), ('drie', 3), ('twee', 2), ('een', 1)]
or without the need for an extra list
[('vier', 4), ('drie', 3), ('twee', 2), ('een', 1)]
or use a lambda expression. sorting dictionary d by value:
and reverse sorting:
oops I meant.. reverse sorting:
Oh my. It's clear you just came over.
This will not produce expected results.
Read the top of this page.
Dictionaries do not hold ordering information!
Using the new key= parameter. With python 2.4 you have the key= parameter, so you can say:
key returns the "sort key" that sort will do the comparison on.
Deferring the sort to iteration is one technique but if you find yourself iterating often then it will kill performance. Python has a number of dictionary implementations that maintain the keys in sorted order. Consider the sortedcontainers module which is pure-Python and fast-as-C implementations. The SortedDict type is a drop-in replacement for Python's built-in dict type. There's also a performance comparison that benchmarks popular implementations against each other.