How do I sort a dictionary by key?
Note: for Python 3.7+, see this answer
Standard Python dictionaries are unordered (until Python 3.7). Even if you sorted the (key,value) pairs, you wouldn't be able to store them in a dict
in a way that would preserve the ordering.
The easiest way is to use OrderedDict
, which remembers the order in which the elements have been inserted:
In [1]: import collections
In [2]: d = {2:3, 1:89, 4:5, 3:0}
In [3]: od = collections.OrderedDict(sorted(d.items()))
In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])
Never mind the way od
is printed out; it'll work as expected:
In [11]: od[1]
Out[11]: 89
In [12]: od[3]
Out[12]: 0
In [13]: for k, v in od.iteritems(): print k, v
....:
1 89
2 3
3 0
4 5
Python 3
For Python 3 users, one needs to use the .items()
instead of .iteritems()
:
In [13]: for k, v in od.items(): print(k, v)
....:
1 89
2 3
3 0
4 5
Sort Dictionary by keys
let dictionary = [
"A" : [1, 2],
"Z" : [3, 4],
"D" : [5, 6]
]
let sortedKeys = Array(dictionary.keys).sorted(<) // ["A", "D", "Z"]
EDIT:
The sorted array from the above code contains keys only, while values have to be retrieved from the original dictionary. However, 'Dictionary'
is also a 'CollectionType'
of (key, value) pairs and we can use the global 'sorted'
function to get a sorted array containg both keys and values, like this:
let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
println(sortedKeysAndValues) // [(A, [1, 2]), (D, [5, 6]), (Z, [3, 4])]
EDIT2: The monthly changing Swift syntax currently prefers
let sortedKeys = Array(dictionary.keys).sort(<) // ["A", "D", "Z"]
The global sorted
is deprecated.
How do I sort a dictionary by value?
Python 3.7+ or CPython 3.6
Dicts preserve insertion order in Python 3.7+. Same in CPython 3.6, but it's an implementation detail.
>>> x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> {k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}
or
>>> dict(sorted(x.items(), key=lambda item: item[1]))
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}
Older Python
It is not possible to sort a dictionary, only to get a representation of a dictionary that is sorted. Dictionaries are inherently orderless, but other types, such as lists and tuples, are not. So you need an ordered data type to represent sorted values, which will be a list—probably a list of tuples.
For instance,
import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))
sorted_x
will be a list of tuples sorted by the second element in each tuple. dict(sorted_x) == x
.
And for those wishing to sort on keys instead of values:
import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))
In Python3 since unpacking is not allowed we can use
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])
If you want the output as a dict, you can use collections.OrderedDict
:
import collections
sorted_dict = collections.OrderedDict(sorted_x)
Sort dictionary by keys in Swift
Dictionary
already has a sorted
method that takes a closure that defines the sorting function. You can sort by keys in the closure, then simply map over the resulting tuples to get the values only.
let sortedDictKeys = dict.sorted(by: { $0.key < $1.key }).map(\.value)
How to sort dictionaries by keys in Python
Dicts don't have an order.
You can call sorted but this just gives you a sorted list of the keys:
>>> sorted(d)
['a', 'b', 'c', 'd']
You can treat it as an iterable and sort the key-value tuples, but then you've just got a list of tuples. That's not the same as a dict.
>>> sorted(d.items())
[
('a', [1, 2, 3]),
('b', ['blah', 'bhasdf', 'asdf']),
('c', ['one', 'two']),
('d', ['asdf', 'wer', 'asdf', 'zxcv'])
]
If you are using Python 2.7 or newer you could also consider using an OrderedDict
.
dict subclass that remembers the order entries were added
For example:
>>> d = collections.OrderedDict(sorted(d.items()))
>>> for k, v in d.items():
>>> print k, v
a [1, 2, 3]
b ['blah', 'bhasdf', 'asdf']
c ['one', 'two']
d ['asdf', 'wer', 'asdf', 'zxcv']
Sorting dictionary keys for the equal values
Here's a high level breakdown of what you'd need to do to get your expected result.
When building your
Counter
, just passall_years
.Dictionaries in python <3.6 are not ordered by default, so you'll need to use an
OrderedDict
.When sorting, make sure you sort by multiple predicates - value first, followed by the key.
from collections import Counter, OrderedDict
c = Counter(all_years)
r = OrderedDict(sorted(d.items(), key=lambda x: (-x[1], x[0])))
OrderedDict([(1995, 9),
(1957, 7),
(2000, 7),
(2003, 7),
(1975, 6),
(2001, 6),
(2009, 6),
(2014, 6),
(1994, 5),
(1997, 5),
(1999, 5),
(2002, 5),
(2010, 5)])
Thanks to Stefan Pochmann for the improvement.
To explain a bit more about key=lambda x: (-x[1], x[0])
, this is how it works:
- You want to sort pairs by the values. So,
x[1]
comes first. You also want to sort in descending order, so negate it. Sincex[1]
is guaranteed to be counts, this should work for anyCounter
output - Next, you want to sort by years, so
x[0]
comes next.
In python 3.6, just pass the result of sorted
to the dict
constructor -
r = dict(sorted(d.items(), key=lambda x: (-x[1], x[0])))
The dictionary is built in the order that pairs are passed to it.
How do I sort a list of dictionaries by a value of the dictionary?
The sorted()
function takes a key=
parameter
newlist = sorted(list_to_be_sorted, key=lambda d: d['name'])
Alternatively, you can use operator.itemgetter
instead of defining the function yourself
from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name'))
For completeness, add reverse=True
to sort in descending order
newlist = sorted(list_to_be_sorted, key=itemgetter('name'), reverse=True)
How to sort Dictionary Keys in Python
This is a duplicated questions:
Python 3.7+
In Python 3.7.0 the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec. Therefore, you can depend on it.
Python 3.6 (CPython)
As of Python 3.6, for the CPython implementation of Python, dictionaries maintain insertion order by default. This is considered an implementation detail though; you should still use collections.OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.
Python <3.6
Use the collections.OrderedDict class when you need a dict that remembers the order of items inserted.
Related Topics
Is Swift Pass by Value or Pass by Reference
How to Dispatch_Sync, Dispatch_Async, Dispatch_After, etc in Swift 3, Swift 4, and Beyond
Cfrunloop in Swift Command Line Program
Swift Random Float Between 0 and 1
How to Create Generic Protocols in Swift
Difference Between Computed Property and Property Set With Closure
Fatal Error: Swapping a Location With Itself Is Not Supported With Swift 2.0
Why Do Self and Self Sometimes Refer to Different Types in Static Functions
Why Create "Implicitly Unwrapped Optionals", Since That Implies You Know There's a Value
How to Save and Read Array of Array in Nsuserdefaults in Swift
Why Optional Constant Does Not Automatically Have a Default Value of Nil
How to Detect If an Skspritenode Has Been Touched
What's the Simplest Way to Convert from a Single Character String to an Ascii Value in Swift