2

Ok - been struggling on this for awhile. I've just started learning Python so very new at this.

I have a list of tuples that needs to be sorted by the ratio of the value in each tuple.

Input:

L = [(1,3), (1,7), (4,8)]

Returns a sorted list:

L = [(1,7), (1,3), (4,8)]

It needs to be sorted using sort and and a custom key. I've seen people use itemgetter and I can't get that version to work either.

My attempt so far:

sorted(L, key = lambda x: [(i[0]/float(i[1])) for i in x])

I've been using this as a guide: How to sort (list/tuple) of lists/tuples?

It seems using itemgetter is the fastest but I can't get that to work either...

Community
  • 1
  • 1
jhub1
  • 611
  • 3
  • 7
  • 19
  • 3
    `key = lambda x: (x[0]/float(x[1]))` – Julien Nov 14 '16 at 04:09
  • 2
    BTW, if you're using Python 2 you can get Python 3 style division by putting `from __future__ import division` at the top of your imports (unless you're using a _very_ ancient version of Python 2). And then you don't need that `float` conversion call. If you want floor division you should always use `//`, even if you don't use that import, since it's better to be explicit about what you're doing. – PM 2Ring Nov 14 '16 at 04:22

1 Answers1

2

You were very close. You didn't need the for loop in your lambda function.

>>> L = [(1,3), (1,7), (4,8)]
>>> sorted(L, key=lambda i: i[0]/float(i[1])) # no need for the for loop
[(1, 7), (1, 3), (4, 8)]
>>> 

You can also make use of operator.itemgetter() like so:

>>> L = [(1,3), (1,7), (4,8)]
>>> from operator import itemgetter
>>> ig = itemgetter(0), itemgetter(1)
>>> sorted(L, key= lambda i: ig[0](i)/float(ig[1](i)))
[(1, 7), (1, 3), (4, 8)]
>>> 
Christian Dean
  • 22,138
  • 7
  • 54
  • 87
  • That's...really depressing how close it was. Just spent several hours trying all different ways. Do you know how to do it via the itemgetter method (supposedly that's fastest?)? – jhub1 Nov 14 '16 at 04:11
  • 1
    There's little benefit to using `itemgetter` like that, since the two `itemgetter` calls are performed _every_ time the lambda is called. It'd be better to do the `itemgetter` calls outside the lambda. Eg, `ig0, ig1 = itemgetter(0), itemgetter(1)` `sorted(L, key= lambda i: ig0(i)/ig1(i))`. But then you might as well just index into the tuple. :) – PM 2Ring Nov 14 '16 at 04:31
  • 1
    @PM2Ring Yout took the words right out of my mouth. That's just what I was about to write up :) But I had neglected the fact of calling `itemgetter ()` outside of the lambda. I'll update that. – Christian Dean Nov 14 '16 at 04:32