python sort json after n elements

Question:

I have a json/dict in the following format:

{
    "top": 590,
    "left": 105, 
    "width": 240, 
    "height": 40,
    "Zarya": "142612a11ad2ca629d2182a51b23d1f2",
    "Kiriko": "4d0528271fd9d0104cd2af0b1c91f4f6",
    "Echo": "175b9c62c57b0d6e18577f352fad4afc",
    "Sojourn": "8ea40548f4472457cfbd46731958a432",
    "Sombra": "319e88daf8a4b53869c6690cd008ebb0",
    "Genji": "b5a7156b9a1921099a884e62f2f7c774",
    "Reaper": "309527687ec1e89f63cfece162c57a66",
    "Ana": "556e9f3ff210729dc9e1cf848c3c579f",
    "Hanzo": "13d164a4f37fd7562b53ede9f5fd2671",
    "Lucio": "d772ddc7e982cd6d714d0a19753c8b32",
    "Torbjorn": "4fdf46b32b3435c714da7a75ba0ccde2",
    "Junkrat": "be29c9729daf9e46606ffa26638641ea",
    "Moira": "0b54634e09e4d108ca248e4e967d15a1",
    "Mei": "90391ff04b11c73e49c48f9b2738d1b0",
    "Dva": "859012ee744e79a630522190ef8ef92c",
    "Soldier 76": "adbd70e889fe6135f372dbd28b7ae5e6",
    "Winston": "1c4245a79b45f1a0b90e78383078cdd3",
    "Tracer": "b5465050c403b020aac35da073d4ab11",
    "Zenyatta": "dccc24bfe5d7b09df7b1387d4c8dfba7",
    "Baptiste": "4d254bc437560ac21780732fc78ffa08",
    "Sigma": "3c85376aee36a901bcbf24b07cf60aa2",
    "Widowmaker": "049092cbd628a54ed22ae5522ca5681c",
    "Orisa": "113acca96744081964854bd94191310a",
    "Ashe": "48ca311fb1b288bb811965e6d84d1786"
}

I would like to sort everything after top, left, width, height alphabetically by the key, while leaving the first 4 keys at the start. How can I accomplish this?

Answers:

Assuming you’re using Python 3.7+ you can use (dct is your dictionary from the question):

items = list(dct.items())
out = dict(items[:4] + sorted(items[4:]))
print(out)

Prints:

{
    "top": 590,
    "left": 105,
    "width": 240,
    "height": 40,
    "Ana": "556e9f3ff210729dc9e1cf848c3c579f",
    "Ashe": "48ca311fb1b288bb811965e6d84d1786",
    "Baptiste": "4d254bc437560ac21780732fc78ffa08",
    "Dva": "859012ee744e79a630522190ef8ef92c",
    "Echo": "175b9c62c57b0d6e18577f352fad4afc",
    "Genji": "b5a7156b9a1921099a884e62f2f7c774",
    "Hanzo": "13d164a4f37fd7562b53ede9f5fd2671",
    "Junkrat": "be29c9729daf9e46606ffa26638641ea",
    "Kiriko": "4d0528271fd9d0104cd2af0b1c91f4f6",
    "Lucio": "d772ddc7e982cd6d714d0a19753c8b32",
    "Mei": "90391ff04b11c73e49c48f9b2738d1b0",
    "Moira": "0b54634e09e4d108ca248e4e967d15a1",
    "Orisa": "113acca96744081964854bd94191310a",
    "Reaper": "309527687ec1e89f63cfece162c57a66",
    "Sigma": "3c85376aee36a901bcbf24b07cf60aa2",
    "Sojourn": "8ea40548f4472457cfbd46731958a432",
    "Soldier 76": "adbd70e889fe6135f372dbd28b7ae5e6",
    "Sombra": "319e88daf8a4b53869c6690cd008ebb0",
    "Torbjorn": "4fdf46b32b3435c714da7a75ba0ccde2",
    "Tracer": "b5465050c403b020aac35da073d4ab11",
    "Widowmaker": "049092cbd628a54ed22ae5522ca5681c",
    "Winston": "1c4245a79b45f1a0b90e78383078cdd3",
    "Zarya": "142612a11ad2ca629d2182a51b23d1f2",
    "Zenyatta": "dccc24bfe5d7b09df7b1387d4c8dfba7",
}
Answered By: Andrej Kesely
data = {
    "top": 590,
    "left": 105, 
    "width": 240, 
    "height": 40,
    "Zarya": "142612a11ad2ca629d2182a51b23d1f2",
    "Kiriko": "4d0528271fd9d0104cd2af0b1c91f4f6",
    "Echo": "175b9c62c57b0d6e18577f352fad4afc",
    "Sojourn": "8ea40548f4472457cfbd46731958a432",
    "Sombra": "319e88daf8a4b53869c6690cd008ebb0",
    "Genji": "b5a7156b9a1921099a884e62f2f7c774",
    "Reaper": "309527687ec1e89f63cfece162c57a66",
    "Ana": "556e9f3ff210729dc9e1cf848c3c579f",
    "Hanzo": "13d164a4f37fd7562b53ede9f5fd2671",
    "Lucio": "d772ddc7e982cd6d714d0a19753c8b32",
    "Torbjorn": "4fdf46b32b3435c714da7a75ba0ccde2",
    "Junkrat": "be29c9729daf9e46606ffa26638641ea",
    "Moira": "0b54634e09e4d108ca248e4e967d15a1",
    "Mei": "90391ff04b11c73e49c48f9b2738d1b0",
    "Dva": "859012ee744e79a630522190ef8ef92c",
    "Soldier 76": "adbd70e889fe6135f372dbd28b7ae5e6",
    "Winston": "1c4245a79b45f1a0b90e78383078cdd3",
    "Tracer": "b5465050c403b020aac35da073d4ab11",
    "Zenyatta": "dccc24bfe5d7b09df7b1387d4c8dfba7",
    "Baptiste": "4d254bc437560ac21780732fc78ffa08",
    "Sigma": "3c85376aee36a901bcbf24b07cf60aa2",
    "Widowmaker": "049092cbd628a54ed22ae5522ca5681c",
    "Orisa": "113acca96744081964854bd94191310a",
    "Ashe": "48ca311fb1b288bb811965e6d84d1786"
}

keys = ['top', 'left', 'width', 'height']

Creating a dictionary with these keys:

data2 = {k: data[k] for k in keys}
# {'left': 105, 'width': 240, 'height': 40, 'top': 590}

Getting all of the other keys:

keys2 = list(data.keys() - list(keys))
# ['Ana', 'Baptiste', 'Zarya', 'Tracer', 'Zenyatta', 'Sigma', 'Dva', 'Torbjorn', 'Mei', 'Orisa', 'Sombra', 'Winston', 'Kiriko', 'Soldier 76', 'Sojourn', 'Ashe', 'Lucio', 'Reaper', 'Moira', 'Widowmaker', 'Junkrat', 'Genji', 'Echo', 'Hanzo']

Sorting those:

keys2.sort()
# ['Ana', 'Ashe', 'Baptiste', 'Dva', 'Echo', 'Genji', 'Hanzo', 'Junkrat', 'Kiriko', 'Lucio', 'Mei', 'Moira', 'Orisa', 'Reaper', 'Sigma', 'Sojourn', 'Soldier 76', 'Sombra', 'Torbjorn', 'Tracer', 'Widowmaker', 'Winston', 'Zarya', 'Zenyatta']

And then updating data2:

data2.update({k: data[k] for k in keys2})
# {'left': 105, 'width': 240, 'height': 40, 'top': 590, 
#  'Ana': '556e9f3ff210729dc9e1cf848c3c579f', 'Ashe': '48ca311fb1b288bb811965e6d84d1786', 'Baptiste': '4d254bc437560ac21780732fc78ffa08', 'Dva': '859012ee744e79a630522190ef8ef92c', 'Echo': '175b9c62c57b0d6e18577f352fad4afc', 'Genji': 'b5a7156b9a1921099a884e62f2f7c774', 'Hanzo': '13d164a4f37fd7562b53ede9f5fd2671', 'Junkrat': 'be29c9729daf9e46606ffa26638641ea', 'Kiriko': '4d0528271fd9d0104cd2af0b1c91f4f6', 'Lucio': 'd772ddc7e982cd6d714d0a19753c8b32', 'Mei': '90391ff04b11c73e49c48f9b2738d1b0', 'Moira': '0b54634e09e4d108ca248e4e967d15a1', 'Orisa': '113acca96744081964854bd94191310a', 'Reaper': '309527687ec1e89f63cfece162c57a66', 'Sigma': '3c85376aee36a901bcbf24b07cf60aa2', 'Sojourn': '8ea40548f4472457cfbd46731958a432', 'Soldier 76': 'adbd70e889fe6135f372dbd28b7ae5e6', 'Sombra': '319e88daf8a4b53869c6690cd008ebb0', 'Torbjorn': '4fdf46b32b3435c714da7a75ba0ccde2', 'Tracer': 'b5465050c403b020aac35da073d4ab11', 'Widowmaker': '049092cbd628a54ed22ae5522ca5681c', 'Winston': '1c4245a79b45f1a0b90e78383078cdd3', 'Zarya': '142612a11ad2ca629d2182a51b23d1f2', 'Zenyatta': 'dccc24bfe5d7b09df7b1387d4c8dfba7'}
Answered By: Chris

Your best hope is to construct a new dictionary by combining two other dictionaries, a sorted one and an unsorted one.

Note that dictionaries are mutable, so in some cases it may be necessary that you actually sort the original dictionary d instead of just replacing it with a new one. This can be done using clear() and then readding the sorted dictionary using update.

Try this runnable example!

#!/usr/bin/env python
d = {
    "top": 590,
    "left": 105,
    "width": 240,
    "height": 40,
    "Zarya": "142612a11ad2ca629d2182a51b23d1f2",
    "Kiriko": "4d0528271fd9d0104cd2af0b1c91f4f6",
    "Echo": "175b9c62c57b0d6e18577f352fad4afc",
    "Sojourn": "8ea40548f4472457cfbd46731958a432",
    "Sombra": "319e88daf8a4b53869c6690cd008ebb0",
    "Genji": "b5a7156b9a1921099a884e62f2f7c774",
    "Reaper": "309527687ec1e89f63cfece162c57a66",
    "Ana": "556e9f3ff210729dc9e1cf848c3c579f",
    "Hanzo": "13d164a4f37fd7562b53ede9f5fd2671",
    "Lucio": "d772ddc7e982cd6d714d0a19753c8b32",
    "Torbjorn": "4fdf46b32b3435c714da7a75ba0ccde2",
    "Junkrat": "be29c9729daf9e46606ffa26638641ea",
    "Moira": "0b54634e09e4d108ca248e4e967d15a1",
    "Mei": "90391ff04b11c73e49c48f9b2738d1b0",
    "Dva": "859012ee744e79a630522190ef8ef92c",
    "Soldier 76": "adbd70e889fe6135f372dbd28b7ae5e6",
    "Winston": "1c4245a79b45f1a0b90e78383078cdd3",
    "Tracer": "b5465050c403b020aac35da073d4ab11",
    "Zenyatta": "dccc24bfe5d7b09df7b1387d4c8dfba7",
    "Baptiste": "4d254bc437560ac21780732fc78ffa08",
    "Sigma": "3c85376aee36a901bcbf24b07cf60aa2",
    "Widowmaker": "049092cbd628a54ed22ae5522ca5681c",
    "Orisa": "113acca96744081964854bd94191310a",
    "Ashe": "48ca311fb1b288bb811965e6d84d1786"
}

# first use a dictionary comprehension to construct a dictionary from only the first four keys
unsorted_part = {k: v for i, (k, v) in enumerate(d.items()) if i < 4}

# now make a dictionary of the sorted second half
items_to_sort = list(d.items())[4:]
sorted_part = dict(sorted(items_to_sort))

# now make a sorted dictionary
new_d = {**unsorted_part, **sorted_part}

# NOTE: if you don't have other references to d that you need to update implicitly as well,
# you could do d={**unsorted_part, **sorted_part}
# HOWEVER: if you do have other references to the original dictionary that you want sorted (i.e. d_ref2)
# you need to clear the original dictionary and re-add all the keys/values in the new order
d_ref2 = d
d.clear()
d.update(new_d)

# now print it out
import json
print(json.dumps(d, indent=2))

<script src="https://modularizer.github.io/pyprez/pyprez.min.js"></script>

Answered By: Modularizer
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.