How to sort (list/tuple) of lists/tuples?

2018-12-31 03:28发布

I have some data either in a list of lists or a list of tuples, like this:

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

And I want to sort by the 2nd element in the subset. Meaning, sorting by 2,5,8 where 2 is from (1,2,3), 5 is from (4,5,6). What is the common way to do this? Should I store tuples or lists in my list?

10条回答
不流泪的眼
2楼-- · 2018-12-31 04:08

itemgetter() is somewhat faster than lambda tup: tup[1], but the increase is relatively modest (around 10 to 25 percent).

(IPython session)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop
查看更多
若你有天会懂
3楼-- · 2018-12-31 04:09
sorted_by_second = sorted(data, key=lambda tup: tup[1])

or:

data.sort(key=lambda tup: tup[1])  # sorts in place
查看更多
深知你不懂我心
4楼-- · 2018-12-31 04:11

Stephen's answer is the one I'd use. For completeness, here's the DSU (decorate-sort-undecorate) pattern with list comprehensions:

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

Or, more tersely:

[b for a,b in sorted((tup[1], tup) for tup in data)]

As noted in the Python Sorting HowTo, this has been unnecessary since Python 2.4, when key functions became available.

查看更多
宁负流年不负卿
5楼-- · 2018-12-31 04:14
from operator import itemgetter
data.sort(key=itemgetter(1))
查看更多
步步皆殇っ
6楼-- · 2018-12-31 04:15

Without lambda:

def sec_elem(s):
    return s[1] 
sorted(data, key=sec_elem) 
查看更多
步步皆殇っ
7楼-- · 2018-12-31 04:17

I just want to add to Stephen's answer if you want to sort the array from high to low, another way other than in the comments above is just to add this to the line:

reverse = True

and the result will be as follows:

data.sort(key=lambda tup: tup[1], reverse=True)
查看更多
登录 后发表回答