2

I have list

value =[(22, 11, 195, 37), (19, 11, 184, 45), (300, 17, 12, 19), (210, 18, 128, 30) (100, 18, 128, 30)]

Now i Need to sort the list in combination of first two values in the list of ascending order.

like this

s = [(19, 11, 184, 45), (22, 11, 195, 37), (300, 17, 12, 19),(100, 18, 128, 30), (210, 18, 128, 30) ]

I used

s = sorted(value, key = lambda x: (x[1], x[0]))

And i ended up sorting the list for 2nd (x[1]) value of the list like this,

s = [(22, 11, 195, 37), (19, 11, 184, 45), (300, 17, 12, 19), (210, 18, 128, 30) (100, 18, 128, 30)]

Are there any methods? I have also tried with operator library, it gives me the same result.

Deepan Raj
  • 385
  • 1
  • 5
  • 16
  • `sorted(value, key = lambda x: (x[1], x[0]))` returns the desired result not the list that starts with `(22, 11, 195, 37)`. – skrx Sep 05 '17 at 14:15
  • Possible duplicate of [Sort a list of tuples depending on two elements](https://stackoverflow.com/questions/9376384/sort-a-list-of-tuples-depending-on-two-elements) – skrx Sep 05 '17 at 14:41

2 Answers2

2

As you understood, the sorted function (and the list.sort method as well) takes a key as optional argument, which tells how to sort the elements.

You're using lambda x: (x[0], x[1]) as key, but your output clearly shows that you want the second member to have more priority than the first. Try with this key:

l = sorted(l, key=lambda t: (t[1], t[0]))

This will give a higher importance to the second member of each tuple.

As expected, the output is:

[(0, 0, 559, 225),
(19, 11, 184, 45),
(22, 11, 195, 37),
(300, 17, 12, 19),
(210, 18, 128, 30)]
Right leg
  • 16,080
  • 7
  • 48
  • 81
  • 2
    Side-note: [Using `operator.itemgetter`](https://docs.python.org/3/library/operator.html#operator.itemgetter) can be a bit more self-documenting here (and a titch faster as a bonus), e.g. `key=itemgetter(1, 0)`. – ShadowRanger Sep 05 '17 at 13:39
  • @ShadowRanger That's smart. I did not know of `itemgetter`. – Right leg Sep 05 '17 at 13:42
  • I used the same s = sorted(calculation, key = lambda x: (x[1], x[0])) And i still not getting sorted for my original list. which i have commented below – Deepan Raj Sep 05 '17 at 13:45
  • [(0, 0, 559, 225), (344, 11, 195, 37), (19, 11, 184, 45), (209, 18, 128, 30), (517, 20, 12, 19), (492, 20, 16, 5), (354, 20, 9, 4), (476, 21, 7, 15), (435, 21, 21, 17), (404, 21, 15, 17), (30, 21, 15, 17), (305, 28, 8, 10), (242, 28, 2, 1), (128, 28, 7, 10), (83, 28, 13, 10), (61, 28, 12, 10), (354, 32, 11, 7), (492, 33, 16, 6), (285, 37, 1, 1), (242, 37, 3, 1), (221, 37, 1, 1), (152, 37, 2, 1), (291, 64, 138, 46), (132, 65, 154, 37), (142, 74, 10, 5), (403, 81, 3, 11), (379, 82, 15, 10), (360, 82, 2, 1)] This is a part of my list – Deepan Raj Sep 05 '17 at 13:46
  • @DeepanRaj I think that the problem is that your criterion is not well-defined. What you asked is rather unclear, but the solution I provided you does work for the sample list you gave. Could you try and define more precisely what behaviour you're expecting? – Right leg Sep 05 '17 at 13:48
  • Say for example i have a list [(22, 11, 195, 37), (19, 11, 184, 45), (300, 17, 12, 19), (210, 18, 128, 30) (100, 18, 128, 30)] I want it like this [(19, 11, 195, 37), (22, 11, 184, 45), (300, 17, 12, 19), (100, 18, 128, 30) (210, 18, 128, 30)] I want to sort ascending order combination of these two values in the list – Deepan Raj Sep 05 '17 at 13:54
1

Okay after a lot of fiddleing i think I did it. Here is my code:

sorted(s, key=lambda x: (x[1] * 1, x[0]))

output is:

[(19, 11, 184, 45), (22, 11, 195, 37), (300, 17, 12, 19), (100, 18, 128, 30), (210, 18, 128, 30)]

Basically what this does is sorts the tuples by index 1 but if two or more tuples have the same number on index 1 it checks their index 0 numbers and sorts them ascendingly.

WholesomeGhost
  • 1,101
  • 2
  • 17
  • 31
  • Actually the list was big, so i made my own list, here is the full list [(0, 0, 559, 225), (344, 11, 195, 37), (19, 11, 184, 45), (209, 18, 128, 30), (517, 20, 12, 19), (492, 20, 16, 5), (354, 20, 9, 4), (476, 21, 7, 15), (435, 21, 21, 17), (404, 21, 15, 17), (30, 21, 15, 17), (305, 28, 8, 10), (242, 28, 2, 1), (128, 28, 7, 10), (83, 28, 13, 10), (61, 28, 12, 10), (354, 32, 11, 7), (492, 33, 16, 6), (285, 37, 1, 1), (242, 37, 3, 1), (221, 37, 1, 1), (152, 37, 2, 1), (291, 64, 138, 46), (132, 65, 154, 37), (142, 74, 10, 5), (403, 81, 3, 11), (379, 82, 15, 10), (360, 82, 2, 1)] – Deepan Raj Sep 05 '17 at 13:40
  • Even this is a part of list. I want to sort for first two values from the list – Deepan Raj Sep 05 '17 at 13:42
  • @DeepanRaj yeah but how do you want it to be sorted? What do you mean by first two values. The question is unclear... – WholesomeGhost Sep 05 '17 at 13:46
  • The first two values in the list say [(0,0,559,225)] in this the first two values 0 and 0, based on the ascending order combination of these two values i need to sort the list – Deepan Raj Sep 05 '17 at 13:48
  • your question is in contradiction with the example you provided – WholesomeGhost Sep 05 '17 at 13:56
  • The question is right, the examples which i made up for that made the entire question wrong.. Hope now you understand what i need – Deepan Raj Sep 05 '17 at 13:58
  • I still don't see that you corrected the example in the question – WholesomeGhost Sep 05 '17 at 14:01
  • @DeepanRaj now it is even more unclear of what you want – WholesomeGhost Sep 05 '17 at 14:09
  • What is it you are unclear about ? Please see the list i have and the expected list i want. – Deepan Raj Sep 05 '17 at 14:11
  • s = sorted(value, key = lambda x: (x[1], x[0])) Please explain what this function will do @nenad. – Deepan Raj Sep 05 '17 at 14:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/153695/discussion-between-nenad-and-deepan-raj). – WholesomeGhost Sep 05 '17 at 14:13