I'm trying to sort a 3D array and having little success. I have read various methods on how this is done for two dimensions, but I can't seem to scale it up.

example array:

r =[[['steve',1, 40], ['steve',3, 20], ['steve',2, 30]],
    [['john',5, 50], ['john',6, 40], ['john',4, 30]]]

I want this to be sorted by the second value, so that it would return:

steve 1 40
steve 2 30
steve 3 20
john 4 30
john 5 50
john 6 40

I have tried this method with itemgetter, but it doesn't seem to work.

from operator import itemgetter
r =[[['steve',1, 40], ['steve',3, 20], ['steve',2, 30]],
    [['john',5, 50], ['john',6, 40], ['john',4, 30]]]
sorted_r = sorted(r, key=itemgetter(1))
print sorted_r

Thanks.

One way directly to print:

r =[[['steve',1, 40], ['steve',3, 20], ['steve',2, 30]],
    [['john',5, 50], ['john',6, 40], ['john',4, 30]]]
print '\n'.join(' '.join(str(item)
                         for item in deep)
                for sub in r
                for deep in sorted(sub))

Edited 6 Years Ago by pyTony: n/a

thanks for the reply. It looks like your suggestion prints in the same order that the list was entered, and not sorted by the second value (1,2,3..). Here is what your code gave me:

1 40 steve
3 20 steve
2 30 steve
5 50 john
6 40 john
4 30 john

After my edit of post the output I get:

steve 1 40
steve 2 30
steve 3 20
john 4 30
john 5 50
john 6 40

What happens if the first "Steve" is 7 instead of 1 -----> , , ], etc. Should it be at the end of the first list or at the end of all of the items? Generally, you would flatten the list and then sort if all items are to be sorted equally.

import itertools
import operator

r =[[['steve',7, 40], ['steve',3, 20], ['steve',2, 30]],
    [['john',5, 50], ['john',6, 40], ['john',4, 30]]]

r_flat = list(itertools.chain(*r))
r_flat.sort(key=operator.itemgetter(1))
print r_flat
#
#output =[['steve', 2, 30], ['steve', 3, 20], ['john', 4, 30], 
#         ['john', 5, 50], ['john', 6, 40], ['steve', 7, 40]]

Edited 6 Years Ago by woooee: n/a

Comments
fine observation

Maybe this code is more appropriate for you, it sorts the flattened version of list by second item instead of sorting normally each deep item (as first ones are equal):

import operator
r =[[['steve',1, 40], ['steve',5, 20], ['steve',2, 30]],
    [['john',2, 50], ['john',6, 40], ['john',4, 30]]]
print '\n'.join(
    ' '.join(str(v)
             for v in value)
    for value in sorted((item for deep in r for item in deep),
                        key = operator.itemgetter(1))
    )
This question has already been answered. Start a new discussion instead.