zayaefs
zayaefs

Reputation: 43

Sorting a list of lists in python alphabetically by "column"

I have a 2d list of characters like

 [['J', 'A', 'M', 'E', 'S'],
 ['F', 'C', 'A', 'A', 'A'],
 ['F', 'A', 'B', 'B', 'B']]

What is the best way to go about sorting the first list alphabetically, with the proceeding lists following, ie:

[['A', 'E', 'J', 'M', 'S'],
['C', 'A', 'F', 'A', 'A'],
['A', 'B', 'F', 'B', 'B']]

Upvotes: 1

Views: 508

Answers (3)

johnsyweb
johnsyweb

Reputation: 141790

The other answers demonstrate how it can be done in one line. This answer illustrates how this works:

Given a list, l:

In [1]: l =  [['J', 'A', 'M', 'E', 'S'],
   ...:  ['F', 'C', 'A', 'A', 'A'],
   ...:  ['F', 'A', 'B', 'B', 'B']]

Group the columns into tuples, by passing each row into zip():

In [2]: zip(*l)
Out[2]: 
[('J', 'F', 'F'),
 ('A', 'C', 'A'),
 ('M', 'A', 'B'),
 ('E', 'A', 'B'),
 ('S', 'A', 'B')]

Sort this list of tuples:

In [3]: sorted(zip(*l))
Out[3]: 
[('A', 'C', 'A'),
 ('E', 'A', 'B'),
 ('J', 'F', 'F'),
 ('M', 'A', 'B'),
 ('S', 'A', 'B')]

Note that if the first list contains duplicate items then this sort is not a stable sort.

Transpose the list again to get three lists of tuples:

In [4]: zip(*sorted(zip(*l)))
Out[4]: 
[('A', 'E', 'J', 'M', 'S'),
 ('C', 'A', 'F', 'A', 'A'),
 ('A', 'B', 'F', 'B', 'B')]

Convert the list of tuples back to a list of lists, using a list comprehension:

In [5]: [list(t) for t in zip(*sorted(zip(*l)))]
Out[5]: 
[['A', 'E', 'J', 'M', 'S'],
 ['C', 'A', 'F', 'A', 'A'],
 ['A', 'B', 'F', 'B', 'B']]

Upvotes: 1

ndpu
ndpu

Reputation: 22561

>>> l = [['J', 'A', 'M', 'E', 'S'],
...  ['F', 'C', 'A', 'A', 'A'],
...  ['F', 'A', 'B', 'B', 'B']]
>>> zip(*sorted(zip(*l)))
[('A', 'E', 'J', 'M', 'S'), ('C', 'A', 'F', 'A', 'A'), ('A', 'B', 'F', 'B', 'B')]

if you need lists in result:

>>> map(list, zip(*sorted(zip(*l))))
[['A', 'E', 'J', 'M', 'S'], ['C', 'A', 'F', 'A', 'A'], ['A', 'B', 'F', 'B', 'B']]

Upvotes: 1

Simeon Visser
Simeon Visser

Reputation: 122346

You can use zip():

>>> [list(t) for t in zip(*sorted(zip(*s)))]
[['A', 'E', 'J', 'M', 'S'], ['C', 'A', 'F', 'A', 'A'], ['A', 'B', 'F', 'B', 'B']]

where s is your list of lists.

Upvotes: 5

Related Questions