How to change the order of keys in a Python 3.5 dictionary, using another list as a reference for keys?
Dicts are "officially" maintained in insertion order starting in 3.7. They were so ordered in 3.6, but it wasn't guaranteed before 3.7. Before 3.6, there is nothing you can do to affect the order in which keys appear.
But OrderedDict
can be used instead. I don't understand your "but it gives me a list" objection - I can't see any sense in which that's actually true.
Your example:
>>> from collections import OrderedDict
>>> d = OrderedDict([('item', 'book'), ('pages', 200),
... ('weight', 1.0), ('price', 25),
... ('city', 'London')])
>>> d # keeps the insertion order
OrderedDict([('item', 'book'), ('pages', 200), ('weight', 1.0), ('price', 25), ('city', 'London')])
>>> key_order= ['city', 'pages', 'item', 'weight', 'price'] # the order you want
>>> for k in key_order: # a loop to force the order you want
... d.move_to_end(k)
>>> d # which works fine
OrderedDict([('city', 'London'), ('pages', 200), ('item', 'book'), ('weight', 1.0), ('price', 25)])
Don't be confused by the output format! d
is displayed as a list of pairs, passed to an OrderedDict
constructor, for clarity. d
isn't itself a list.
How to return dictionary keys as a list in Python?
This will convert the dict_keys
object to a list
:
list(newdict.keys())
On the other hand, you should ask yourself whether or not it matters. It is Pythonic to assume duck typing -- if it looks like a duck and it quacks like a duck, it is a duck. The dict_keys
object can be iterated over just like a list
. For instance:
for key in newdict.keys():
print(key)
Note that dict_keys
doesn't support insertion newdict[k] = v
, though you may not need it.
Python 3.6+: Equality of two dictionaries with same keys but in different order
Dictionaries are hash tables, order is not supposed to matter. In python 3.6+ dictionaries are in insertion order but that is just how they are implemented. Order doesn't matter for equality. If you want order to matter in equality use an OrderedDict.
from collections import OrderedDict
d1 = OrderedDict({'foo':123, 'bar':789})
d2 = OrderedDict({'bar':789, 'foo':123})
print(d1 == d2) # False
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 3For 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
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)
Python 3.5: OrderedDict -- overwrite the order of self when sorted?
Unfortunately overwriting self doesn't work as it breaks the reference to the original object. Thus one can achieve the desired result by using super
in conjunction with one of OrderedDict
's methods as follows:
def sort_by_value(self):
post_sort =sorted(self.items(), key=lambda item: item[1]))
for key, value in post_sort:
super(DumbDictionary, self).move_to_end(key)
Related Topics
How to Insert String Value into Specific Column Value on Python Pandas
Numpy Array Typeerror: Only Integer Scalar Arrays Can Be Converted to a Scalar Index
Python - Having Trouble Opening a File With Spaces
How to Remove \N from a List Element
How to Clear All Variables in the Middle of a Python Script
How to Get the Return Value from a Thread in Python
In Python, How to Split a String and Keep the Separators
Removing Rows and Columns in Python CSV Module
Find Value in Dictionary Using Regex in Python
Make a Batch File Run a Python Code With Arguments
Find the Item With Maximum Occurrences in a List
Printing a Multiplication Table With Nested Loops
Best Way to Get the Max Value in a Spark Dataframe Column
How to Find a Minimum Value in a 2D Array Without Using Numpy or Flattened in Python