Karamzov
Karamzov

Reputation: 403

Accessing nested keys in Python

I have a nested dictionary as below

entry = {
    0: {"Q": 0},
    1: {"W": 2, "E": 3, "N": 5, "S": 4, "Q": 0},
    2: {
        "N": {
            "Q": {"E"}
        }
    },
}

When I try to access only the keys for the key 1, I get the following:

>>> print(entry[1].keys())
dict_keys(['W', 'E', 'N', 'S', 'Q'])

But for key 2 it only returns the top key and not the nested key.

>>> print(entry[2].keys())
dict_keys(['N'])  

Why is it not returning the nested key of the dictionary?

Upvotes: 3

Views: 6956

Answers (6)

Adam Erickson
Adam Erickson

Reputation: 6373

Depending on what your goals are, here are functions to collect a nested list of dict keys and pretty-print this list:

from typing import Union

def list_keys(hashmap: dict) -> list[str]:
    """Collect list of nested key names."""
    keys = []
    for k in hashmap.keys():
        keys.append(k)
        if type(hashmap.get(k)) is dict:
            keys.append(fieldnames(hashmap.get(k)))
    return keys

def pprint(obj: Union[list,dict]) -> None:
    """Pretty print dicts as JSON."""
    print(json.dumps(obj, indent=4))
    return None

entry = {
    0: {"Q": 0},
    1: {"W": 2, "E": 3, "N": 5, "S": 4, "Q": 0},
    2: {
        "N": {
            "Q": "E"
        }
    },
}

keys = list_keys(entry)
print(keys, '\n', entry)
pprint(keys)
pprint(entry)

Here, I have removed the depth-4 level so that it will properly serialize to JSON for printing.

Upvotes: 0

Gavriel Cohen
Gavriel Cohen

Reputation: 4643

For only keys, Use simple recorsive function:

def recursive_items(dict_name):
    for key, value in a.items():
        if type(value) is dict:
            yield (key)
            yield from recursive_items(value)

# print the keys 
for key in recursive_items(a):
   print(key)

This function will benefit for any nested dictionary

Upvotes: 0

FloMei
FloMei

Reputation: 66

if you wanted to check all nested keys, you could create a loop function that checks the type of your looked up data and iterates over it if it is another dictionary, like

def print_nested_keys(d):
    for k in d.keys():
        print(k)
        if type(d[k]) == dict:
            print('nested dict detected - recursing...')
            print_nested_keys(d[k])

here, whenever one of the keys in your dictionary points to another dictionary, you call the function recursively to read through the lower-level dictionary keys. of course, you could always append the keys that you find in a list to return by your function in the end, if you want such a list.

Upvotes: 1

Edward Minnix
Edward Minnix

Reputation: 2947

dict.keys only returns the top level keys of the dictionary. If you want to get all nested keys of a dictionary, you will need to define your own function.

# interface for dictionary-like objects
from collections.abc import Mapping

def nested_keys(d) -> set:
    """
    Return a set containing all nested keys.
    """
    # If it is not a dict-like object, return an empty set
    if not isinstance(d, Mapping):
        return set()

    keys = d.keys()
    for v in d.values():
        # Update the keys set with the keys in each value by using the union (or) operator: |
        keys |= nested_keys(v)

    return keys

Upvotes: 1

A-y
A-y

Reputation: 793

keys()doesn't work that way.

keys()

Return a new view of the dictionary’s keys

Your nested dictionnary is a completely separate dict, and you can get its own keys with its own keys() method :

entry[2]['N'].keys()

If you want to recursively get all the keys inside nested dictionnaries, you will have to implement a method for that :

entry = {0: {"Q": 0},
         1: {"W": 2, "E": 3, "N": 5, "S": 4, "Q": 0},
         2: {"N": { "Q":{"E"}}},
}


def rec_keys(dictio):
    keys = []
    for (key,value) in dictio.items():
        if isinstance(value, dict):
            keys.extend(rec_keys(value))
        else:
            keys.append(key)
    return keys

print(rec_keys(entry))
# ['Q', 'Q', 'W', 'N', 'S', 'E', 'Q']

Upvotes: 6

Gunnar
Gunnar

Reputation: 19

When you run print(entry[2].keys())

you're asking python "What keys exist in the data corresponding to key '2'? (which in your case is another dictionary)" The answer to which is just 'N'. This is because

entry[2]

is

{"N": { "Q":{"E"}}

which has the single key 'N' and the data '{"Q":{"E"}}'

Upvotes: 1

Related Questions