1

I am needing to sort a list that contains tuples inside. I can sort them using key=lambda. The list is larger than 1000 elements.

>>> a = [(<object>, 4), (<object>, 5), (<object>, -2)....]
>>> b = sorted(a, key=lambda tup: tup[1])

Is there a faster way to accomplish this?

4
  • Nah it's cool. I think itemgetter is a lot better than use lambda, but mainly for clean code. I generally don't ask "faster", I often ask "better", "cleaner", or "more intuitive". Typically, for performance, you ain't gonna need it. However, you will restructure your code, and many many times. Write it so you can easily read your code, easily restructure it as need be. Itemgetter is great for this example, it just so happens to be better for reasons that are mostly not what you asked for. Commented Jun 26, 2015 at 2:29
  • Thank you for that point. I will see if there are any other responses, and I will select your answer if there are no others tomorrow. Commented Jun 26, 2015 at 2:31
  • 1
    That is a good thing to focus on, readability. I will keep it in mind. Commented Jun 26, 2015 at 2:32
  • Part of the reason I emphasize it is because I'm a somewhat new programmer, and I shot myself in the foot badly early on by focusing on optimization. I optimized where there were no bottlenecks, and introduced artificial bottlenecks due to the lack of readable code and the way I structured my code. Which ironically made my code much worse (the root of all evil) than if I had never optimized. Commented Jun 26, 2015 at 2:37

1 Answer 1

5

You can use itemgetter

>>> from operator import itemgetter
>>> a = [(None, 4), (None, 5), (None, -2)]
>>> b = sorted(a, key=itemgetter(1))
>>> b
[(None, -2), (None, 4), (None, 5)]

Now if you want to look at the performance, here is itemgetter:

In [3]: %timeit sorted(a, key=itemgetter(1))
1000000 loops, best of 3: 732 ns per loop

In [4]: %timeit sorted(a, key=lambda tup: tup[1])
1000000 loops, best of 3: 804 ns per loop

So, not too dramatic for a small list. Let's upscale this:

In [1]: import random
In [2]: a = [(i, random.randint(0, 100)) for i in range(100000)]
In [3]: %timeit sorted(a, key=itemgetter(1))
10 loops, best of 3: 30.5 ms per loop
In [4]: %timeit sorted(a, key=lambda tup: tup[1])
10 loops, best of 3: 35.6 ms per loop

So still a slightly faster approach even after upscaling. However, I use itemgetter because it's clean code, not because it's faster. Write clean code over performance, and optimize if necessary. 1000 elements is nothing: it's better you know what you're doing.

Just remember, premature [or unnecessary] optimization is the root of all evil. Especially for such a small data set, where it takes milliseconds to complete the entire task.

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

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.