Search code examples
pythonpython-3.xdictionarydefaultdict

Getting values out of a default dict


I have a defaultdict of shape:

defaultdict(<function __main__.construct_dicts.<locals>.<lambda>>,
            {1: defaultdict(set, {'A': {0, 1}}),
             2: defaultdict(set, {'A': {1, 3}, 'E': {12, 14}}),
             3: defaultdict(set,
                         {'A': {3, 6},
                          'C': {4, 7, 10},
                          'D': {5, 8, 11},
                          'E': {9, 12}})})

How can I put all the values into three lists, like:

lst_1 = [[0, 1]]
lst_2 = [[1, 3], [12, 14]]
lst_3 = [[3, 6], [4, 7], [7, 10], [5, 8], [8, 11], [9, 12]]

where, for a set of odd values, I repeat the last value in the old pair as the new value in the new pair, for example {5, 8, 11} became [5, 8], [8, 11].


Solution

  • You can use a itertools.zip_longest to generate the value pairs you want, and then use enumerate to index the resulting list so that you can populate the missing values from sets with odd-numbered items from the pair of the last index:

    from itertools import chain, zip_longest
    d = {
        1: {'A': {0, 1}},
        2: {'A': {1, 3}, 'E': {12, 14}},
        3: {'A': {3, 6}, 'C': {4, 7, 10}, 'D': {5, 8, 11}, 'E': {9, 12}}
    }
    lst1, lst2, lst3 = [[[i[n - 1][1], j[0]] if j[1] is None else list(j) for n, j in enumerate(i)] for i in [list(chain.from_iterable([list(zip_longest(l[::2], l[1::2])) for l in map(sorted, v.values())])) for v in d.values()]]
    

    This outputs:

    [[0, 1]]
    [[1, 3], [12, 14]]
    [[3, 6], [4, 7], [7, 10], [5, 8], [8, 11], [9, 12]]