0

I got a list of lists:

A = [[5, 0], [4, 1], [0, 31/3], [0, 4/3], [1, 0], [5/4, 7/4]]

and want to sort it like this:

[[5, 0], [4, 1], [5/4, 7/4], [1, 0], [0, 31/3], [0, 4/3]]

With A.sort(reverse=True) I sort it at least for the first entry. I got many lists because they pretend to be nxm matrices. So I can't transform the outer list to a set because "lines" (inner lists) may get deleted that way.

Edit: another example:

A = [[0, 168, 14], [0, 156, 13], [64, 64, 104], [0, 48, 4], [0, 0, 272], [8, 8, 13], [0, 0, 153]]

should be sorted as:

[[64, 64, 104], [8, 8, 13], [0, 168, 14], [0, 156, 13], [0, 48, 4], [0, 0, 272], [0, 0, 153]]
Tonechas
  • 13,398
  • 16
  • 46
  • 80
TheDude
  • 55
  • 1
  • 9
  • 3
    Sorry why does `A.sort(reverse=True)` not work? The results match your desired outputs in both examples. – T. Silver Apr 04 '16 at 02:56
  • 2
    I was wondering the same thing... what exactly is your question? – Reblochon Masque Apr 04 '16 at 02:56
  • Also, that first example is probably not going to do what you want since it is integer division and 5/4 == 7/4 == 4/3 == 1 – aspotic Apr 04 '16 at 02:59
  • Unless it is python3 @apsotic – Reblochon Masque Apr 04 '16 at 03:01
  • See: http://stackoverflow.com/questions/4174941/how-to-sort-a-list-of-lists-by-a-specific-index-of-the-inner-list – MANA624 Apr 04 '16 at 03:05
  • I will use fractions so those numbers 4/3 for example arent a problem. I mean that I need a functiion which sorts my list of lists by the value of the numbers reversely and if theres a 0 head to the next row to sort and so on. – TheDude Apr 04 '16 at 03:06
  • @MANA624 I already checked this solution before making this question. It doesnt help me. Unfortunately! – TheDude Apr 04 '16 at 03:07
  • @TheDude So what is the different between the output that you expected and what A.sort(reverse=True) resulted in? – SDBot Apr 04 '16 at 03:35
  • @SDBot I dont know why but only line 0 was sorted. After restarting OS it worked as intended. – TheDude Apr 04 '16 at 04:17

3 Answers3

1
from __future__ import division

A = [[0, 168, 14], [0, 156, 13], [64, 64, 104], [0, 48, 4], [0, 0, 272], [8, 8, 13], [0, 0, 153]]
B = [[5, 0], [4, 1], [0, 31/3], [0, 4/3], [1, 0], [5/4, 7/4]]

def getKey3(item):
    return item[0], item[1], item[2]

def getKey2(item):
    return item[0], item[1] 

print sorted(A, key=getKey3, reverse=True)   
print sorted(B, key=getKey2, reverse=True)

Output:

[[64, 64, 104], [8, 8, 13], [0, 168, 14], [0, 156, 13], [0, 48, 4], [0, 0, 272], [0, 0, 153]]
[[5, 0], [4, 1], [1.25, 1.75], [1, 0], [0, 10.333333333333334], [0, 1.3333333333333333]]
Tonechas
  • 13,398
  • 16
  • 46
  • 80
roadrunner66
  • 7,772
  • 4
  • 32
  • 38
  • Thank you so much! That worked. After I restarted my notebook A.sort(reverse=True) worked also... Sry to waste your time! – TheDude Apr 04 '16 at 04:13
1

For a quick hack way to do it, tested on the 2 samples you provided:

A = [[5, 0], [4, 1], [0, 31/3], [0, 4/3], [1, 0], [5/4, 7/4]]
B = [[0, 168, 14], [0, 156, 13], [64, 64, 104], [0, 48, 4], [0, 0, 272], [8, 8, 13], [0, 0, 153]]

def K(ar):
  return sum(n*10**(4*i) for i, n in enumerate(reversed(ar)))

A = sorted(A, reverse=True, key=K)
print('result a', A)
B = sorted(B, reverse=True, key=K)
print('result b', B)

For better performance & known mathematical correctness, though, I'd see what the docs say about sorting & comparisons using numpy arrays

edit: also see https://wiki.python.org/moin/HowTo/Sorting/

Nathan Smith
  • 475
  • 4
  • 12
  • Thank you very much. I dont know if I'm allowed to use packages like sage, numpy etc. because I have to test my scripts on a server with a unmodable python version. – TheDude Apr 04 '16 at 04:15
  • you're welcome, hope it helps. btw, I picked those constants on an intuitive basis of what seemed large enough to at least mostly preserve the ordering rules we want but still small enough not to take up too much memory & time for reasonable sized arrays. If this is for something important, figure it out on paper & pencil whether these are good values to use – Nathan Smith Apr 04 '16 at 04:47
  • @TheDude, I added a link w/ some clean & reliable approaches to sorting that keep w/In the standard library – Nathan Smith Apr 04 '16 at 05:12
1

I think the other solutions proposed here are overcomplicated, sorted(A, reverse=True) should do.

Demo:

In [15]: A = [[5, 0], [4, 1], [0, 31/3], [0, 4/3], [1, 0], [5/4, 7/4]]

In [16]: B = [[0, 168, 14], [0, 156, 13], [64, 64, 104], [0, 48, 4], [0, 0, 272], [8, 8, 13], [0, 0, 153]]

In [17]: sorted(A, reverse=True)
Out[17]: 
[[5, 0],
 [4, 1],
 [1.25, 1.75],
 [1, 0],
 [0, 10.333333333333334],
 [0, 1.3333333333333333]]

In [18]: sorted(B, reverse=True)
Out[18]: 
[[64, 64, 104],
 [8, 8, 13],
 [0, 168, 14],
 [0, 156, 13],
 [0, 48, 4],
 [0, 0, 272],
 [0, 0, 153]]

Notice that if you are using Python 2 you need to add from future import __division__ at the beginning of your script to avoid integer division.

Tonechas
  • 13,398
  • 16
  • 46
  • 80