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.
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.
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'
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'}]
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}
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}
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.
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.
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'
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'}]
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}
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}