Search code examples
pythondictionaryfor-loopnested

how do I return key, value of nested key and value of second nested value


I'm sure there must be a relatively easy way to do this but I'm either missing it completely or simply can't seem to grasp it. I'm usually fairly competent at finding the answer I need but I'm having no luck. Hoping someone will be able to help.

If I have the below dictionary how do I print (or return) The key, a value from a set of the nested values, and a value from the second nested set?

people = {
        "123": {
            "name": "Danny",
            "age": 100,
            "animal": "cat",
            "last_action": {
                "status": "Offline",
                "timestamp": 1664651202,
                "relative": "50 minutes ago"
            },
            "status": {
                "description": "Okay",
                "details": "",
                "state": "Okay",
                "color": "green",
                "until": 0
            },
            "number": "Six"
        },
        "456": {
            "name": "Suzy",
            "age": 42,
            "animal": dog,
            "last_action": {
                "status": "Offline",
                "timestamp": 1664636683,
                "relative": "4 hours ago"
            },
            "status": {
                "description": "Not Okay",
                "details": "",
                "state": "Okay",
                "color": "green",
                "until": 0
            },
            "number": "Twelve"
        },"789": {
            "name": "Chris",
            "age": 23,
            "animal": "horse",
            "last_action": {
                "status": "Offline",
                "timestamp": 1664636683,
                "relative": "4 hours ago"
            },
            "status": {
                "description": "Okay",
                "details": "",
                "state": "Okay",
                "color": "green",
                "until": 0
            },
            "number": "Two"
        }  

Specifically, in the above I want to print (or assign to a variable for other uses) the below;

123 Danny Okay
456 Suzy Not Okay
789 Chris Okay

I KNOW there must be a for loop for this and have tried several combinations of

key for key in people.items()
key for value in.....

I've also tried things along the lines of

numbers = people.keys()

and then using the numbers variable in the for loop as well.

I'm sorry I'm doing such a poor job of explaining the solutions I've tried but I can't access my current version at the moment and I've re-written it so many times I no longer remember them all.

It's also complicated (to me anyway) by the fact that I need the three elements as variables, so rather than just 789 Chris Okay I want {numbers}{name}{status}.


Solution

  • You could use a list comprehension over people.items():

    res = [ f'{k} {v["name"]} {v["status"]["description"]}' for k, v in people.items() ]
    

    Output:

    ['123 Danny Okay', '456 Suzy Not Okay', '789 Chris Okay']
    

    Alternatively you could just iterate in a for loop:

    for k, v in people.items():
        status = f'{k} {v["name"]} {v["status"]["description"]}'
        print(status)   # or do something else with it
    

    Output:

    123 Danny Okay
    456 Suzy Not Okay
    789 Chris Okay
    

    Or, if you want a set of discrete variables:

    number, name, status = map(list, zip(*[ (k, v["name"], v["status"]["description"]) for k, v in people.items() ]))
    number
    # ['123', '456', '789']
    name
    # ['Danny', 'Suzy', 'Chris']
    status
    # ['Okay', 'Not Okay', 'Okay']
    

    Or in the for loop:

    numbers = people.keys()
    for number in numbers:
        name = people[number]['name']
        status = people[number]['status']['description']
        print(f'{number} {name} {status}')   # or do something else with them
    

    Output:

    123 Danny Okay
    456 Suzy Not Okay
    789 Chris Okay