Converting python dictionary to unique key-value pairs
<p>I want to convert a python dictionary to a list which contains all possible key-value pair. For example, if the dict is like:</p>

<pre><code>{
    "x": {
            "a1": { "b": {
                            "c1": { "d": { "e1": {}, "e2": {} } },
                            "c2": { "d": { "e3": {}, "e4": {} } }
                        }
                },
            "a2": { "b": {
                            "c3": { "d": { "e1": {}, "e5": {} } },
                            "c4": { "d": { "e6": {} } }
                        }
                 }
       }
}
</code></pre>

<p>I would like to get a list like:</p>

<pre><code>[
  { "x": "a1", "b": "c1", "d": "e1" },
  { "x": "a1", "b": "c1", "d": "e2" },
  { "x": "a1", "b": "c2", "d": "e3" },
  { "x": "a1", "b": "c2", "d": "e4" },
  { "x": "a2", "b": "c3", "d": "e1" },
  { "x": "a2", "b": "c3", "d": "e5" },
  { "x": "a2", "b": "c4", "d": "e6" }
]
</code></pre>

<p>I am struggling to write a recursive function.
I have written this, but it is not working</p>

<pre><code>def get_list(groups, partial_row):
    row = []
    for k, v in groups.items():
        if isinstance(v, dict):
            for k2, v2 in v.items():
                partial_row.update({k: k2})
                if isinstance(v2, dict):
                    row.extend(get_list(v2, partial_row))
                else:
                    row.append(partial_row)

    return row
</code></pre>

<p>Alternative solution:</p>

<pre><code>from pprint import pprint
dic = {
    "x": {
            "a1": { "b": {
                            "c1": { "d": { "e1": {}, "e2": {} } },
                            "c2": { "d": { "e3": {}, "e4": {} } }
                        }
                },
            "a2": { "b": {
                            "c3": { "d": { "e1": {}, "e5": {} } },
                            "c4": { "d": { "e6": {} } }
                        }
                 }
       }
}


def rec(dic, path=[], all_results=[]):
    if not dic:
        # No items in the dictionary left, add the path
        # up to this point to all_results

        # This is based on the assumption that there is an even
        # number of items in the path, otherwise you output format
        # makes no sense
        even_items = path[::2]
        odd_items = path[1::2]
        result = dict(zip(even_items, odd_items))
        all_results.append(result)
        return all_results

    for key in dic:
        # Make a copy of the current path
        path_cp = list(path)
        path_cp.append(key)
        all_results = rec(dic[key], path_cp, all_results)

    return all_results


results = rec(dic)

pprint(results)
</code></pre>

<p>Output:</p>

<pre><code>[{'b': 'c2', 'd': 'e4', 'x': 'a1'},
 {'b': 'c2', 'd': 'e3', 'x': 'a1'},
 {'b': 'c1', 'd': 'e1', 'x': 'a1'},
 {'b': 'c1', 'd': 'e2', 'x': 'a1'},
 {'b': 'c3', 'd': 'e5', 'x': 'a2'},
 {'b': 'c3', 'd': 'e1', 'x': 'a2'},
 {'b': 'c4', 'd': 'e6', 'x': 'a2'}]
</code></pre>

python list dictionary flatten