0

Is there a way to return a list of all dictionary keys in the provided input (at all levels)?
The keys should be ordered by level, for example:

{
    "A": 1,
    "B": [{
        "B1": 1,
        "B2": 1
    }, {
        "B3": 1,
        "B4": 1
    }],
    "C": {
        "C1": 1,
        "C2": 1
    }
}

I have tried using dict.keys() and dict.items() but did not get the desired output.
The output should be like this ["A", "B", "C", "B1", "B2", "B3", "B4", "C1", "C2"].
Any help is appreciated.

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39

2 Answers2

1

I would do a recursive function:

d = {
    "A": 1,
    "B": [{
        "B1": 1,
        "B2": 1
    }, {
        "B3": 1,
        "B4": 1
    }],
    "C": {
        "C1": 1,
        "C2": 1
    }
}

def flatten(d, lst=None):
    if not lst:
        lst = []
    if isinstance(d, list):
        for item in d:
            lst = flatten(item, lst)
    elif isinstance(d, dict):
        for k in d.keys():
            lst.append(k)
        for v in d.values():
            lst = flatten(v, lst)
    return lst

print(flatten(d)) # Output: ['A', 'B', 'C', 'B1', 'B2', 'B3', 'B4', 'C1', 'C2']

EDIT: Above code assumes you're using Python 3.7+ where dict are ordered by default. If you're running an older version, you can use collection.OrderedDict instead while initializing d to have the same behavior.

Hampus Larsson
  • 3,050
  • 2
  • 14
  • 20
  • Recheck the output it also prints None with the list , it's because of the return of the lst at the end of the recursion – DaVinci May 29 '20 at 12:04
  • Agree with recursive approach. You might consider incorporating https://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable to capture any iterable object that may contain dictionaries. – jpf May 29 '20 at 12:04
  • 1
    Also might add assumption of using ordered dictionaries (implicit in Python 3, but not Python 2). – jpf May 29 '20 at 12:09
  • Could you give a brief info on how the above code works? @HampusLarsson – Nikhil kumar Jun 06 '20 at 08:14
  • @Nikhilkumar It's a recursive function. That means that the function calls itself if certain conditions match. If `d` is a list, then it tries to call `flatten` once for each value inside of the list. If `d` is a dictionary, then it will first append `lst` with each of the keys inside of it, it will then loop through all of the values inside of the dictionary and call `flatten` on them individually. During all the recursive calls to the function `flatten` the `lst` variable refers to the same list, so whenever it's appended all references to that list is updated aswell. FInally we return `lst` – Hampus Larsson Jun 06 '20 at 10:11
0

I think i found it

#In order to convert nested list to single list
import more_itertools
a={"A": 1,
    "B": [{
        "B1": 1,
        "B2": 1
    }, {
        "B3": 1,
        "B4": 1
    }],
    "C": {
        "C1": 1,
        "C2": 1
    }
}
dic_key=[]
for i in a:
    dic_key.append(i)
for i in a:
    if type(a[i]) is list :
        dic_key+=list(map(lambda x:list(x.keys()),a[i]))
    elif type(a[i]) is dict:
        dic_key+=list(map(lambda x: x,a[i]))
print(list(more_itertools.collapse(dic_key)))
DaVinci
  • 868
  • 1
  • 7
  • 25