3

First of all, apologies if this too naive (I am a beginner). I have the following type of list of lists, which I would like to first sort by the last member of the inner list in ascending order:

data =  [[1, .45, 0], [2, .49, 2], [3, .98, 0], [4, .82, 1], [5, .77, 1], [6, .98, 2] ]

I accomplish this by using : sorted(data,key=operator.itemgetter(2),reverse = True), which gives me:

[[1, .45, 0], [3, .98, 0],[4, .82, 1], [5, .77, 1], [2, .49, 2], [6, .98, 2]]

Now, I would like to sort within the sub-lists i.e. first sort the list with its last member as '0' using the middle member as the key, in descending order. Then sort the sub-list with '1' as its last member and so on. Note that number of elements in each sub-list are different and are not know. The final list should look like this:

[[3, .98, 0],[1, .45, 0], [4, .82, 1], [5, .77, 1], [6, .98, 2],[2, .49, 2] ]

The list is actually quite huge, therefore I am looking for an efficient implementation. Any guidance would be appreciated !

6
  • I think your second example is backwards...you sorted reverse right? Commented Jun 27, 2012 at 5:22
  • Apologies, I guess I made a mistake while typing. It should have been reverse = False. Commented Jun 27, 2012 at 5:26
  • Just to delve a little more into this (as an answer has already been provided), what exactly are you trying to do before this step? There might be a better way of achieving your goal, rather than worrying about the inner sort component. For instance, if you're reading this data in from somewhere, it might make sense to sort as you load. It might also be possible to use generators rather than lists/dicts. It might help if you post another question asking "is there a better way to achieve X". Just a thought :) Commented Jun 27, 2012 at 5:53
  • @JoshSmeaton: Thanks a lot for your suggestion ! I am generating these list, which form the values in a dictionary via a computation which can be thought of as, for avalues in someset(A) , for bvalues in someset(B) return avalues + bvalues i.e say return the sum of all the pairwise combinations in both the sets. The keys would then be the values in setA and the list would be its [corresponding sum will all the elements, paired with the corresponding element of setB]. I will also try to form a separate question, but any feedback is highly appreciated ! Commented Jun 27, 2012 at 6:10
  • @R.Bahl you might want to look into the itertools package - it may have some functions that'd be useful to you. For instance, efficiently generating the pairwise combinations. Where you're getting the data from initially should also be a possible place for optimisation. The problem seems very abstract to me without more context. But yeah like I suggested, possibly another question might yield some nice solution. Good luck. Commented Jun 27, 2012 at 6:22

2 Answers 2

4
>>> data =  [[1, .45, 0], [2, .49, 2], [3, .98, 0], [4, .82, 1], [5, .77, 1], [6, .98, 2] ]
>>> sorted(data, key=lambda x:(x[2], -x[1]))
[[3, 0.98, 0], [1, 0.45, 0], [4, 0.82, 1], [5, 0.77, 1], [6, 0.98, 2], [2, 0.49, 2]]

You can add extra terms to the lambda as required

Sign up to request clarification or add additional context in comments.

5 Comments

Gah. You entered this 6 minutes ago, and it notified me just as I was submitting this (lag). Almost word for word
Thanks !! This works perfectly. Just to follow up on my earlier comment that the list is huge, for starters I am storing them in a dictionary as key: value pairs where , values are these lists and keys are some numbers. As the number of keys and the size of the list runs into thousands, it quickly becomes infeasible to rum them from ram. What should be the most optimized method of doing it ? I am kind of hesitant to store these huge dictionaries in memory while I sort the list associated with each key.
@R.Bahl: Sort each one in place via: aList.sort(...) ? Then you aren't generating any overly duplicated memory.
@jdi: I agree with you. But, since the number of keys is large (>10,000) and each list corresponding to the value of the key may contain >20,000 small inner lists (which we just sorted), then is doing it in memory a good method of approaching it ?
@R.Bahl, if you have enough RAM, doing the sort in memory is preferable. Sounds like you would need quite a lot of RAM to do this sort, but maybe it is possible with 16GB or so
1

You can pass sorted multiple keys:

data =  [[1, .45, 0], [2, .49, 2], [3, .98, 0], [4, .82, 1], [5, .77, 1], [6, .98, 2] ]
sorted(data, key=lambda x: (x[2], -x[1]))

[[3, 0.98, 0],
 [1, 0.45, 0],
 [4, 0.82, 1],
 [5, 0.77, 1],
 [6, 0.98, 2],
 [2, 0.49, 2]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.