3

i have a list of tuples which is :

[('g', 10, 2), ('o', 6, 11), ('v', 2, 4), ('t', 1, 15), ('x', 40, 3), ('m', 4, 4), ('k', 10, 2), ('f', 14, 1), ('p', 70, 90), ('l', 21, 7), ('n', 1, 27), ('a', 39, 70), ('d', 11, 10), ('h', 21, 10), ('c', 10, 19), ('b', 8, 1), ('e', 30, 39), ('i', 23, 29), ('r', 8, 7), ('q', 2, 2), ('s', 18, 86)]

and I'm struggling about how to sort them so they can be placed like this:

[('p', 70, 90), ('a', 39, 70), ('s', 18, 84), ('è', 27, 45), ('e', 30, 39), ('i', 23, 29), ('x', 40, 3), ('h', 21, 10), ('c', 10, 19), ('l', 20, 7), ('d', 11, 10), ('o', 6, 11), ('t', 1, 15), ('f', 14, 1), ('r', 8, 7), ('g', 10, 2), ('k', 10, 2), ('n', 1, 11), ('b', 8, 1), ('m', 4, 4), ('v', 2, 4), ('q', 2, 2)]

It should be the addition of the second and third element of the tuple , and when they are the same ex. (a,10,9) and (b,9,10) they should be sorted alphabetically. It's written in python 3.5 and I can't call any library

over96
  • 37
  • 5
  • You subjet line says sort by 2nd or 3rd, but your words say "the addition of the 2nd and 3rd element... when they are the same sort alphabetically" – doctorlove Nov 02 '16 at 16:12
  • Possible duplicate of [How to sort (list/tuple) of lists/tuples?](http://stackoverflow.com/questions/3121979/how-to-sort-list-tuple-of-lists-tuples) – MooingRawr Nov 02 '16 at 16:13
  • @Doctorlove Sorry I'm going to edit it , i was about to ask the wrong question – over96 Nov 02 '16 at 16:15

3 Answers3

6

You can set a tuple as the key to sort your list:

sorted(lst, key = lambda x: (sum(x[1:]), x[0]))

In this way, it will firstly sort by the sum of the last two elements of the tuple and then by the first element of the tuple.

And if you like the result in descending order, as @Moses commented, you can specify the the reverse parameter to be True:

sorted(lst, key = lambda x: (sum(x[1:]), x[0]), reverse = True)

Update: To handle descending, ascending order differently, since the sum here is numeric, you can negate the sum as well. In this way, it will be sorted in descending order for the sum but alphabetically for the first letter.

sorted(lst, key = lambda x: (-sum(x[1:]), x[0]))
Psidom
  • 209,562
  • 33
  • 339
  • 356
  • 2
    A `reverse=True` would be required considering OP's output – Moses Koledoye Nov 02 '16 at 16:18
  • Does it need a `reverse = True` or did i misunderstand the question? – doctorlove Nov 02 '16 at 16:19
  • 1
    @doctorlove Yep. OP's result seems to prefer descending order. – Psidom Nov 02 '16 at 16:22
  • @Psidom That answer sorts alphabetically only if the first element of the tuple is a 1 character word? Or it works for words of x lenght aswell? – over96 Nov 02 '16 at 16:25
  • @over96 It shouldn't matter how long the word is. It will compare starting from the first letter of the word just like how list is compared in python. – Psidom Nov 02 '16 at 16:27
  • @Psidom oh wait i got where the problem is , when i use reverse = True it does the reverse with the alphabethical order aswell – over96 Nov 02 '16 at 16:29
  • That's correct. I don't think you can specify the sum in descending order and word in ascending order at the same time with `sorted()` function only. – Psidom Nov 02 '16 at 16:32
  • @Psidom Well I "can't use modules which are not in the standard library" – over96 Nov 02 '16 at 16:41
  • You can negate the `sum` to solve this specific problem here since it's numeric. – Psidom Nov 02 '16 at 16:45
3
sorted(a, key=lambda x: (sum(x[1:3]), x[0]))

Where a is your list. If you need reversed:

sorted(a, key=lambda x: (sum(x[1:3]), x[0]), reverse=True)
Alex
  • 1,141
  • 8
  • 13
0
a = [('g', 10, 2), ('o', 6, 11), ('v', 2, 4), ('t', 1, 15),
     ('x', 40, 3), ('m', 4, 4), ('k', 10, 2), ('f', 14, 1),
     ('p', 70, 90), ('l', 21, 7), ('n', 1, 27), ('a', 39, 70),
     ('d', 11, 10), ('h', 21, 10), ('c', 10, 19), ('b', 8, 1),
     ('e', 30, 39), ('i', 23, 29), ('r', 8, 7), ('q', 2, 2),
     ('s', 18, 86)]

Create a function that will return the sum of the items and use that function a the sort key. I like to use operator.itemgetter() when extracting items from iterables.

import operator
second_third_first_items = operator.itemgetter(1, 2, 0)
def key(thing):
    *two_three, one = second_third_first_items(thing)
    return (sum(two_three), one)
a.sort(key = key, reverse = True)

key without operator.itemgetter

def key(thing):
    one, *two_three = thing[:3]
    return (sum(two_three), one)
wwii
  • 23,232
  • 7
  • 37
  • 77