Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - How to sort multidimensional list to two-dimensional list?

Tags:

How i can sort multidimensional list to two-dimensional list?

Multidimensional input: [8, [6, 7, [-1], [4, [[10]]], 2], 1]

Desired two-dimensional output: [[8, 1], [6, 7, 2], [-1, 4], [], [10]]

all same depth list items need to be in same list.

like image 937
Martenoff Avatar asked Dec 05 '18 12:12

Martenoff


People also ask

How do you sort a multi dimensional list in Python?

Use sorted() with a lambda function to sort a multidimensional list by column. Call sorted(iterable, key=None) with key set to a lambda function of syntax lambda x: x[i] to sort a multidimensional list iterable by the i th element in each inner list x .

How do you sort a 3d array in Python?

You can simply pass your array to the numpy. sort() function that takes an array-like object as an argument. The function returns a copy of the sorted array rather than sorting it in-place. If you want to sort an array in-place, you need to create an ndarray object using the numpy.


2 Answers

The idea is basically the same that the one in @TerryA answer, but using setdefault and checking at the end of the for loop if something of the depth was added:

lst = [8, [6, 7, [-1], [4, [[10]]], 2], 1]


def depths(l):
    def flatten(l, start=0, depth={}):

        for e in l:
            if isinstance(e, list):
                flatten(e, start=start + 1, depth=depth)
            else:
                depth.setdefault(start, []).append(e)
         if start not in depth:
            depth[start] = []

    d = {}
    flatten(l, depth=d)

    return [d[i] for i in range(max(d) + 1)]


result = depths(lst)
print(result)

Output

[[8, 1], [6, 7, 2], [-1, 4], [], [10]]
like image 139
Dani Mesejo Avatar answered Oct 13 '22 00:10

Dani Mesejo


You could perhaps use a defaultdict here to measure the depth of each element, along with recursion:

from collections import defaultdict
L = [8, [6, 7, [-1], [4, [[10]]], 2], 1]
res = defaultdict(list)
def myfunc(L, depth):
    for i in L:
        if isinstance(i, list):
            myfunc(i, depth+1)
        else:
            res[depth].append(i)

myfunc(L, 0)

The defaultdict will then look like this:

defaultdict(<class 'list'>, {0: [8, 1], 1: [6, 7, 2], 2: [-1, 4], 4: [10]})

You'll then need to translate the defaultdict back to what you want. Note that the default dict will not contain an empty list because it can't detect it (ie: [[10]] and [10] are both lists), but what it will have is a gap in the range (notice how the depth 3 is missing in the defaultdict).

final = []
for i in range(max(res)+1):
    if i not in res:
        final.append([])
    else:
        final.append(res[i])

print(final)

Very messy, I'm sure improvements could be made.

like image 42
TerryA Avatar answered Oct 13 '22 00:10

TerryA