This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Ordering a nested dictionary in python with json format
Type: enhancement Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: Umar Asghar, serhiy.storchaka
Priority: normal Keywords:

Created on 2019-10-08 19:57 by Umar Asghar, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
test.py Umar Asghar, 2019-10-08 20:17
bug.py Umar Asghar, 2019-10-08 22:00
Messages (5)
msg354228 - (view) Author: Umar Asghar (Umar Asghar) Date: 2019-10-08 19:57
Python does not preserve ordering in JSON format. I have tested it out but it's not working. Here is my code.

# Python3 code to demonstrate 
# Sort nested dictionary by key 
# using OrderedDict() + sorted() 
from collections import OrderedDict 
from operator import getitem 
import json

# initializing dictionary 
test_dict = {'Nikhil' : { 'roll' : 24, 'marks' : 17}, 
            'Akshat' : {'roll' : 54, 'marks' : 12}, 
            'Akash' : { 'roll' : 12, 'marks' : 15}} 

# printing original dict 
print("The original dictionary : " + str(test_dict)) 

# using OrderedDict() + sorted() 
# Sort nested dictionary by key 
res = OrderedDict(sorted(test_dict.items(), 
    key = lambda x: getitem(x[1], 'marks'))) 

print("The sorted dictionary by marks is : " + str(res))
# Output
# The sorted dictionary by marks is : OrderedDict([('Akshat', {'marks': 12, 'roll': 54}), ('Akash', {'marks': 15, 'roll': 12}), ('Nikhil', {'marks': 17, 'roll': 24})])

res = json.dumps(res)

# print result 
print("The sorted dictionary by marks is : (json)")
print(json.loads(res)) 
# Output
# The sorted dictionary by marks is : 
# {'Akash': {'marks': 15, 'roll': 12}, 'Akshat': {'marks': 12, 'roll': 54}, 'Nikhil': {'marks': 17, 'roll': 24}}
Does anyone suggest any solution for it?

It's different than a simple dictionary. It only targets the nested dictionary ordering. Please don't mark it a duplication of simple dictionary ordering with JSON. thanks
msg354229 - (view) Author: Umar Asghar (Umar Asghar) Date: 2019-10-08 20:00
I guess it exists in all Python versions. I have tested in both Python 2 and Python 3.

Python 2.7.15+ (default, Jul  9 2019, 16:51:35) 
[GCC 7.4.0] on linux2

Python 3.6.8 (default, Aug 20 2019, 17:12:48) 
[GCC 8.3.0] on linux
msg354230 - (view) Author: Umar Asghar (Umar Asghar) Date: 2019-10-08 20:25
I have recently attached the file, please review it as a code reference.
msg354237 - (view) Author: Umar Asghar (Umar Asghar) Date: 2019-10-08 22:00
Please ignore the above shared sample data in the above code and consider this one.

this is the exact code that is misbehaving in python 2.7


# Sort nested dictionary by key
# using OrderedDict() + sorted()
from collections import OrderedDict
from operator import getitem
import json

# initializing dictionary
test_dict = {'3' : { 'roll' : 24, 'marks' : 17},
            '2' : {'roll' : 54, 'marks' : 12},
            '1' : { 'roll' : 12, 'marks' : 15}}

# printing original dict
print("The original dictionary : " + str(test_dict))

# using OrderedDict() + sorted()
# Sort nested dictionary by key
res = OrderedDict(sorted(test_dict.items(),
    key = lambda x: getitem(x[1], 'marks')))

print("The sorted dictionary by marks is : " + str(res))
# Output
# The sorted dictionary by marks is : OrderedDict([('2', {'roll': 54, 'marks': 12}), ('1', {'roll': 12, 'marks': 15}), ('3', {'roll': 24, 'marks': 17})])

res1 = json.dumps(res)

# print result
print("The sorted dictionary by marks is : (json)")
print(json.loads(res1))
# Output
# The sorted dictionary by marks is : (json)
# {u'1': {u'roll': 12, u'marks': 15}, u'3': {u'roll': 24, u'marks': 17}, u'2': {u'roll': 54, u'marks': 12}}
msg354251 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-10-09 06:18
Dictionary preserve the insertion order starting from Python 3.7 (actually from 3.6, but it was not guarantied). I am surprised that you got different result in 3.6. I cannot reproduce it.

In older Python versions you can pass object_pairs_hook=OrderedDict to json.loads() to preserve the insertion order. The regular dictionary cannot preserve it, by its structure.
History
Date User Action Args
2022-04-11 14:59:21adminsetgithub: 82595
2019-10-09 06:18:06serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg354251

resolution: out of date
stage: resolved
2019-10-08 22:02:34Umar Asgharsettype: enhancement
2019-10-08 22:00:15Umar Asgharsetfiles: + bug.py

messages: + msg354237
2019-10-08 20:26:47Umar Asgharsetversions: + Python 2.7, - Python 3.9
2019-10-08 20:25:48Umar Asgharsetmessages: + msg354230
2019-10-08 20:17:27Umar Asgharsetfiles: + test.py
2019-10-08 20:00:18Umar Asgharsetmessages: + msg354229
versions: + Python 3.9
2019-10-08 19:57:40Umar Asgharcreate