3

I have created a 2D matrix like this:

45  67  Row  Fine
25  22  Abe  Real
58  54  Abe  Noon

Each column is a list. The values in the rows are connected together, so the values in the third row with the indexnumber 2 belong to each other.

I want to sort the rows, first on the third row, and then on the fourth row, so that it becomes:

58  54  Abe  Noon  
25  22  Abe  Real 
45  67  Row  Fine

I don't know what way to go. I could sort one list, the one with the values of the third column. Then find out the new indexnumbers and compare them with the old. Then I could adjust the other lists as well, so that all rows are correct again. But then I still need to sort the fourth row.

I see some code for sorting a list of lists here , but I then need lists of rows instead of columns (if I understand it well).

Or is creating a dictionary a smart way to go?

Community
  • 1
  • 1
JOVERN
  • 65
  • 6

2 Answers2

1

You have a list of columns. To make it into a list of rows, you can just use zip:

iterable_of_rows = zip(*my_list_of_columns)

Combining that with the typical way to do these sorts:

import operator
sorted_list_of_rows = sorted(zip(*my_list_of_columns), key = operator.itemgetter(2,3))
list_of_columns = list(zip(*sorted_list_of_rows))

And testing:

>>> my_list_of_columns = [[45,25,48],[67,22,54],["Row","Abe","Abe"],["Fine","Real","Noon"]]
>>> import operator
>>> sorted_list_of_rows = sorted(zip(*my_list_of_columns), key = operator.itemgetter(2,3))
>>> list_of_columns = list(zip(*sorted_list_of_rows))
>>> list_of_columns
[(48, 25, 45), (54, 22, 67), ('Abe', 'Abe', 'Row'), ('Noon', 'Real', 'Fine')]
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Note that `operator.itemgetter(2,3)` is equivalent to `lambda x: (x[2],x[3])`, but it is marginally faster (and some would argue that it's cleaner, although I don't really have a preference...) – mgilson Sep 10 '12 at 12:32
  • 1
    I don't like the fact that it requires an `import` :) – Lev Levitsky Sep 10 '12 at 12:35
  • 1
    @LevLevitsky -- I actually feel the same way. But, I know a lot of people are very interested in splitting hairs over micro-optimizations which are unlikely to lead to anything noticeable, otehrs find it more readable (although I think both forms are pretty easy to grok if you understand `lambda`) ... Anyway, the form which I use really depends on the mood I'm in that particular day (probably should standardize it in my code, but ... currently I'm the only one who uses it anyway ;^). – mgilson Sep 10 '12 at 12:41
  • Thanks a lot! I didn't know the zip command and with the "operator" it is very elegant. – JOVERN Sep 26 '12 at 13:37
0

Working with a list of columns directly is troublesome, but you can use zip and work with rows:

>>> print(data)
[[45, 25, 58], [67, 22, 54], ['Row', 'Abe', 'Abe'], ['Fine', 'Real', 'Noon']]

>>> print(sorted(zip(*data), key=lambda x: (x[2], x[3])))
[(58, 54, 'Abe', 'Noon'), (25, 22, 'Abe', 'Real'), (45, 67, 'Row', 'Fine')]
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175