Search code examples
pythondictionarymultidimensional-arraytreepivot-table

How do I create a nested `dict` of arrays in Python?


I need to 'pivot' an array of arrays like this:

mytable = [
    [117, 12, 'wer'],
    [117, 23, 'hgr'],
    [42, 33, 'hgj'],
    [910, 27, 'sfr'],
    [910, 31, 'mhn'],
    [910, 98, 'wlc'],
    [453, 11, 'nlj'],
    [453, 65, 'nfg'],
    [312, 17, 'fyg'],
    [312, 44, 'gfn']
]

into a nested dict, like this:

mytree = {
    117: [[12, 'wer'], [23, 'hgr']],
    42 : [[33, 'hgj']],
    910: [[27, 'sfr'], [31, 'mhn'], [98, 'wlc']],
    453: [[11, 'nlj'], [65, 'nfg']],
    312: [[17, 'fyg'], [44, 'gfn']]
}

This first column is what will be pivoted and used as the branch, under which there will be joined - as an array of one or more arrays - all of the original arrays less the first element (which is 'promoted' to 'parent'). Think Excel Pivot Table.

This does not work:

mytree = {}

for arr in mytable:
    toadd = {arr[0]: [[arr[1], arr[2]]}
    mytree.append(toadd)

I accept I may need to change the exact output structure to include more quoted key names if the example above is not accepted as valid object syntax.


Solution

  • You can use setdefault method from dict

    mytree = {}
    
    for (k, *arr) in mytable:
        mytree.setdefault(k, []).append(arr)
    

    Output:

    >>> mytree
    {117: [[12, 'wer'], [23, 'hgr']],
     42: [[33, 'hgj']],
     910: [[27, 'sfr'], [31, 'mhn'], [98, 'wlc']],
     453: [[11, 'nlj'], [65, 'nfg']],
     312: [[17, 'fyg'], [44, 'gfn']]}
    

    Or with defaultdict from collections module:

    from collections import defaultdict
    
    mytree = defaultdict(list)
    
    for (k, *arr) in mytable:
        mytree[k].append(arr)
    

    Output:

    >>> mytree
    defaultdict(list,
                {117: [[12, 'wer'], [23, 'hgr']],
                 42: [[33, 'hgj']],
                 910: [[27, 'sfr'], [31, 'mhn'], [98, 'wlc']],
                 453: [[11, 'nlj'], [65, 'nfg']],
                 312: [[17, 'fyg'], [44, 'gfn']]})