0

I am trying to retain the whole contents of a nested dictionary but only with its contents reordered..

This is an example of my nested dictionaries (pardon the long example..) -

{
    "pages": {
        "rotatingTest": {
            "elements": {
                "apvfafwkbnjn2bjt": {
                    "name": "animRot_tilt40_v001", 
                    "data": {
                        "description": "tilt testing", 
                        "project": "TEST", 
                        "created": "26/11/18 16:32", 
                    }, 
                    "type": "AnimWidget", 
                    "uid": "apvfafwkbnjn2bjt"
                }, 
                "p0pkje1hjcc9jukq": {
                    "name": "poseRot_positionD_v003", 
                    "data": {
                        "description": "posing test for positionD", 
                        "created": "10/01/18 14:16", 
                        "project": "TEST", 
                    }, 
                    "type": "PosedWidget", 
                    "uid": "p0pkje1hjcc9jukq"
                }, 
                "k1gzzc5uy1ynqtnj": {
                    "name": "animRot_positionH_v001", 
                    "data": {
                        "description": "rotational posing test for positionH", 
                        "created": "13/06/18 14:19", 
                        "project": "TEST", 
                    }, 
                    "type": "AnimWidget", 
                    "uid": "k1gzzc5uy1ynqtnj"
                }
            }
        }, 
        "panningTest": {
            "elements": {
                "7lyuri8g8u5ctwsa": {
                    "name": "posePan_positionZ_v001", 
                    "data": {
                        "description": "panning test for posZ", 
                        "created": "04/10/18 12:43", 
                        "project": "TEST", 
                    }, 
                    "type": "PosedWidget", 
                    "uid": "7lyuri8g8u5ctwsa"
                }
            }
        }, 
        "zoomingTest": {
            "elements": {
                "prtn0i6ehudhz475": {
                    "name": "posZoom_positionH_v010", 
                    "data": {
                        "description": "zoom test", 
                        "created": "11/10/18 12:42", 
                        "project": "TEST", 
                    }, 
                    "type": "PosedWidget", 
                    "uid": "prtn0i6ehudhz475"
                }
            }
        }
    }, 
    "page_order": [
        "rotatingTest", 
        "zoomingTest", 
        "panningTest"
    ]
}

and this is my code:

for k1, v1 in test_dict.get('pages', {}).items():
    return (sorted(v1.get('elements').items(), key=lambda (k2,v2): v2['data']['created']))

In the code, keys such as the page_order, pages etc are missing... Or if there is/ are any commands where it will enables me to retain the 'whole' of the dictionary?

Appreciate in advance for any advice.

yan
  • 631
  • 9
  • 30
  • 1
    Lists have order, dictionaries typically do not. You can make it so, but it usually doesn't help you get things done. Consider modifying your schema to treat `elements` like a list, with each list item being what is now the sub-dictionary, and you'll be able to order the list in a way that persists. – erik258 Dec 10 '18 at 23:08

1 Answers1

1

If you're using Python 3.7, a dict will preserve insert order. Otherwise, you need to use an OrderedDict.Additionally, you need to convert the date string to a date to get the correct sort order:

from datetime import datetime

def sortedPage(d):
    return {k: {'elements': dict(sorted(list(v['elements'].items()), key=lambda tuple: datetime.strptime(tuple[1]['data']['created'], '%d/%m/%y %H:%M')))} for k,v in d.items()}

output = {k: sortedPage(v) if k == 'pages' else v for k,v in input.items()}
ic3b3rg
  • 14,629
  • 4
  • 30
  • 53
  • thank you for you code. Wondering if it is really necessary to change the items within elements into a list? Can it not be stick back to as a dict? – yan Dec 11 '18 at 19:04
  • Yes, actually you can. If you're using 3.7, dicts retain insertion order (I just learned this). If you're using 3.6 or less, you need to use an `OrderedDict`: https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6/39980744 – ic3b3rg Dec 11 '18 at 19:09
  • Okay I will test it out. By the way, I just realized that the unique id values key are being omitted out if using your code. – yan Dec 11 '18 at 21:30
  • I am trying to understand the code. So is the tuple consists of the 'values' of the 'elements' keys? – yan Dec 11 '18 at 23:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185095/discussion-between-yan-and-ic3b3rg). – yan Dec 11 '18 at 23:13