By roflwaffle


2009-12-08 15:53:35 8 Comments

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?

13 comments

@user11502624 2019-05-15 07:36:38

from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])

@Ville 2019-03-18 01:43:40

Another alternative is to use Pandas dataframe as it guarantees the order and the index locations of the items in a dict-like structure.

@Himanshu Kanojiya 2019-01-29 09:27:02

You can do the same thing which i did for dictionary.

Create a list and empty dictionary:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', '[email protected]']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items

@Mohit Dabas 2015-01-30 07:29:33

Rather than explaining the theoretical part, I'll give a simple example.

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}

@tyan 2016-03-31 02:50:37

Is there a way to mass assign OrderedDict like the Dict type?

@Tonechas 2016-04-25 19:08:18

OrderedDict indeed solves the problem, but... in this particular example you get exactly the same result using a standard dictionary

@twasbrillig 2016-05-03 20:13:59

@Tonechas: I just tried the example with a standard dictionary, and got {'aol': 1, 'foo': 3} So I think it's a good illustrative example.

@holdenweb 2016-09-01 08:19:03

There's a lesson for everyone: it was discovered (I think around the 2.4 release) that Python's predictable hashing might give rise to security vulnerabilities, so now there's no guarantee that even two different runs of the same code will give the same ordering in a standard dict.

@JavaSa 2017-06-06 11:43:44

Why can't we pass some format of the order we want to mass initialize with our values? Instead of assigning in each line one value? (python2.7)

@Ruud Althuizen 2018-09-12 11:06:52

@tyan you can call OrderedDict.update() with an iterable containing key-value pairs: d1.upate([(key1, val1), (key2, val2)]).

@mgilson 2012-06-11 14:25:10

Note that this answer applies to python versions prior to python3.7. CPython 3.6 maintains insertion order under most circumstances as an implementation detail. Starting from Python3.7 onward, it has been declared that implementations MUST maintain insertion order to be compliant.


python dictionaries are unordered. If you want an ordered dictionary, try collections.OrderedDict.

Note that OrderedDict was introduced into the standard library in python 2.7. If you have an older version of python, you can find recipes for ordered dictionaries on ActiveState.

@tpk 2017-07-17 10:28:37

see @martijn's post above. From python 3.6 onwards, dict supports insertion ordering.

@Martijn Pieters 2016-09-16 17:40:58

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.

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).

@handle 2017-05-16 10:17:31

That nice (change of) behaviour does not seem to be documented in docs.python.org/3/library/stdtypes.html#dict - I was looking for a hint on the order. docs.python.org/3/tutorial/datastructures.html#dictionaries mentions "unordered", "arbitrary order".

@Martijn Pieters 2017-05-16 10:20:53

@handle and that's because this is an implementation detail, as Chris notes. The What's new in Python 3.6 docs mention it.

@Wrenbjor 2018-01-15 16:57:13

This solved my issue. I was using Python to sort and align a ton of things from a spreadsheet that was feeding another system. The order was critical. I updated to 3.6.4 (Latest Hombrew Version) and it came out in order without messing with it!

@Martijn Pieters 2018-04-09 21:24:47

@Chris_Rands: quite right, added that in.

@David Culbreth 2019-04-17 19:44:50

@handle, if you look at the first page you linked in your comment now, you'll find the following: Changed in version 3.7: LIFO order is now guaranteed. In prior versions, popitem() would return an arbitrary key/value pair.

@nealous3 2016-09-02 01:05:58

You can't really do what you want with a dictionary. You already have the dictionary d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}created. I found there was no way to keep in order once it is already created. What I did was make a json file instead with the object:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

I used:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

then used:

print json.dumps(r)

to verify.

@Martijn Pieters 2017-06-13 06:21:43

So why not start with an OrderedDict from a list? The JSON file doesn't really add anything here.

@nealous3 2017-06-14 10:33:58

Yes, list is more useful to keep order but the answer was in regards to the question about ordering dictionaries. Just letting people know about the limitations of using a dictionary and giving them a possible work around if they need to use a dictionary for some reason.

@Martijn Pieters 2017-06-14 10:38:19

But that part is already covered by much older answers, dating back to 2012.

@smushface 2014-06-16 21:17:04

I came across this post while trying to figure out how to get OrderedDict to work. PyDev for Eclipse couldn't find OrderedDict at all, so I ended up deciding to make a tuple of my dictionary's key values as I would like them to be ordered. When I needed to output my list, I just iterated through the tuple's values and plugged the iterated 'key' from the tuple into the dictionary to retrieve my values in the order I needed them.

example:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

It's a tad cumbersome, but I'm pressed for time and it's the workaround I came up with.

note: the list of lists approach that somebody else suggested does not really make sense to me, because lists are ordered and indexed (and are also a different structure than dictionaries).

@Hrvoje T 2018-04-27 21:53:28

Great solution. I will use it to write json to file, always in the same order.

@pelos 2013-07-04 20:47:11

if you would like to have a dictionary in a specific order, you can also create a list of lists, where the first item will be the key, and the second item will be the value and will look like this example

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

@BHSPitMonkey 2014-05-01 00:09:32

That is not a "dictionary" because you cannot lookup items by their key without searching through the entire collection (taking O(n) time).

@SunSparc 2015-08-25 21:21:55

Yes, it is not a dictionary, but, depending on the situation, it could provide a valid solution the problem of the original poster.

@pelos 2018-03-22 15:54:36

he didn't say exactly how we wanted, just that want to be able to order them =), as always there is plenty of ways to do one thing.

@eumiro 2012-06-11 14:26:02

from collections import OrderedDict
OrderedDict((word, True) for word in words)

contains

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

If the values are True (or any other immutable object), you can also use:

OrderedDict.fromkeys(words, True)

@lvc 2012-06-11 14:37:44

Worth noting, of course, that the 'immutable' part isn't a hard and fast rule that Python will enforce - its "only" a good idea.

@andilabs 2014-06-05 13:47:06

be aware that solutions like: OrderedDict(FUTURE=[], TODAY=[], PAST=[]) wont't work, when mentioned aproach: OrderedDict([('FUTURE', []), ('TODAY', []), ('PAST', [])]) will keep order.

@tyan 2016-03-31 02:57:59

@andi I got another problem,when using jsonify, the OrderedDict seems lost it's order when generate the json data.Anyway to solve this?

@tyan 2016-03-31 03:01:54

github.com/pallets/flask/issues/974 this can be used to solve the problem..

@sertsedat 2018-09-04 08:05:25

@Evan 2011-06-02 15:46:31

I had a similar problem when developing a Django project. I couldn't use OrderedDict, because I was running an old version of python, so the simple solution was to use Django's SortedDict class:

https://code.djangoproject.com/wiki/SortedDict

@Rasmus Kaj 2009-12-08 16:09:27

Generally, you can design a class that behaves like a dictionary, mainly be implementing the methods __contains__, __getitem__, __delitem__, __setitem__ and some more. That class can have any behaviour you like, for example prividing a sorted iterator over the keys ...

@Fire Lancer 2009-12-08 15:57:43

Dictionaries will use an order that makes searching efficient, and you cant change that,

You could just use a list of objects (a 2 element tuple in a simple case, or even a class), and append items to the end. You can then use linear search to find items in it.

Alternatively you could create or use a different data structure created with the intention of maintaining order.

@scharette 2018-11-27 00:20:28

Dictionaries will use an order that makes searching efficient Finally, someone pointed it out.

Related Questions

Sponsored Content

23 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 2845269 View
  • 2683 Score
  • 23 Answer
  • Tags:   python dictionary

34 Answered Questions

[SOLVED] How do I sort a dictionary by value?

18 Answered Questions

[SOLVED] How do you sort a dictionary by value?

8 Answered Questions

[SOLVED] How to remove a key from a Python dictionary?

15 Answered Questions

[SOLVED] Add new keys to a dictionary?

39 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

14 Answered Questions

[SOLVED] How to return multiple values from a function?

19 Answered Questions

49 Answered Questions

[SOLVED] Sort a Map<Key, Value> by values

8 Answered Questions

[SOLVED] Java Class that implements Map and keeps insertion order?

Sponsored Content