Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep keys/values in same order as declared?

I have a dictionary that I declared in a particular order and want to keep it in that order all the time. The keys/values can't really be kept in order based on their value, I just want it in the order that I declared it.

So if I have the dictionary:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10} 

It isn't in that order if I view it or iterate through it, is there any way to make sure Python will keep the explicit order that I declared the keys/values in?

like image 495
roflwaffle Avatar asked Dec 08 '09 15:12

roflwaffle


People also ask

Does dict keys preserve order?

It's a dictionary subclass specially designed to remember the order of items, which is defined by the insertion order of keys. This changed in Python 3.6. The built-in dict class now keeps its items ordered as well.

Is the order of key-value pairs always the same in a dictionary?

Here you specify the key order upfront, the returned values will always have the same order even if the dict changes, or you use a different dict.

Does Python keys and values return the same order?

Yes, what you observed is indeed a guaranteed property — keys() , values() and items() return lists in congruent order if the dict is not altered. iterkeys() &c also iterate in the same order as the corresponding lists.


1 Answers

From Python 3.6 onwards, the standard dict type maintains insertion order by default.

Defining

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10} 

will result in a dictionary with the keys in the order listed in the source code.

This was achieved by using a simple array with integers for the sparse hash table, where those integers index into another array that stores the key-value pairs (plus the calculated hash). That latter array just happens to store the items in insertion order, and the whole combination actually uses less memory than the implementation used in Python 3.5 and before. See the original idea post by Raymond Hettinger for details.

In 3.6 this was still considered an implementation detail; see the What's New in Python 3.6 documentation:

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).

Python 3.7 elevates this implementation detail to a language specification, so it is now mandatory that dict preserves order in all Python implementations compatible with that version or newer. See the pronouncement by the BDFL. As of Python 3.8, dictionaries also support iteration in reverse.

You may still want to use the collections.OrderedDict() class in certain cases, as it offers some additional functionality on top of the standard dict type. Such as as being reversible (this extends to the view objects), and supporting reordering (via the move_to_end() method).

like image 172
Martijn Pieters Avatar answered Sep 17 '22 23:09

Martijn Pieters