How to make a specific key the first key in a dictionary?

Question:

I want make a specific element of each dictionary the first element in a list of dictionaries. How would I do this, or is it even possible given that dictionaries are unordered?

I don’t want to use .sort() by itself or OrderedDict because both will not bring the desired element to the top of the keys as the keys are alphabetically ordered. Is there a way to use the lamba keyword in combination with sort in Python 2.7 to do this?

Ex:

I want b to be the first key

{'a': 1, 'b': 2, 'c': 3}


{'b': 2, 'a': 1, 'c': 3}

CONTEXT:

I have a large set of dictionaries where each dictionary represents a bunch of info about a job. Each dictionary has a code that identifies the job. My superior would like to have this code moved to the top of its dictionary.

Asked By: goldisfine

||

Answers:

is it even possible given that dictionaries are unordered?

No, it’s not possible. Any solution you find that seems to do the trick will not be guaranteed to work between python versions, builds, code contexts, etc. If you want an ordered data type, you’ll need something other than a dictionary.

Answered By: Brionius

Dicts don’t have any top or bottom. You can try something like this:

>>> from itertools import chain
>>> dic = {'a': 1, 'b': 2, 'c': 3}
>>> key = 'b'
for k in chain(key, (dic.viewkeys()-key)):
    print k, dic[k]
...     
b 2
a 1
c 3

Better use an OrderedDict.

>>> from collections import OrderedDict
>>> key = 'b'
>>> dic1 = OrderedDict((k,dic[k]) for k in chain(key, (dic.viewkeys()-key)))
>>> next(iter(dic1))
'b'
Answered By: Ashwini Chaudhary

Wrap your dict in a list and move your code out. Instead of

data = {'code':'this is the code', 'some':'other', 'stuff':'here'}

do

data = ['this is the code', {'some':'other', 'stuff':'here'}]
Answered By: tdelaney

Python dicts have a well-defined order since python 3.6 so this is entirely possible now, although it was not possible when the question was asked.
One way to do this is first create one dict containing only ‘b’ and one dict containing the rest, then merging them in the right order.

x = {'a': 1, 'b': 2, 'c': 3}
first_dict = {'b':x['b']}                          # create a dict for only b
second_dict = {k:v for k,v in x.items() if k!='b'} # create a dict for the rest
y = {**first_dict, **second_dict}

Result:

y = {'b': 2, 'a': 1, 'c': 3}
Answered By: Jelmer

As others have pointed out, Python’s dictionaries are now ordered (by insertion order) since Python 3.6. The cleanest way I know to move a single item to the front of a dictionary is to use pop():

d = {'a': 1, 'b': 2, 'c': 3}  # original dict
d = {'b': d.pop('b'), **d}  # new order
print(d)
# {'b': 2, 'a': 1, 'c': 3}

Python guarantees left-to-right execution order, so you know the pop takes place before expanding **d, which means 'b' will occur at the front and not later in the **d expansion.

If you’re going to be doing this a bunch and you don’t want to write the key twice, or if the key is going to be a computed expression, you can make a helper function:

def plop(d, key):
    return {key: d.pop(key)}

d = {'a': 1, 'b': 2, 'c': 3}  # original dict
d = {**plop(d, 'b'), **d}  # new order
print(d)
# {'b': 2, 'a': 1, 'c': 3}
Answered By: Ken Williams
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.