如何按给定索引处的元素对列表/元组的列表/元组进行排序?

问题:如何按给定索引处的元素对列表/元组的列表/元组进行排序?

我在列表列表或元组列表中都有一些数据,如下所示:

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

我想按子集中的第二个元素排序。这意味着,由2,5,8,其中排序2(1,2,3)5是从(4,5,6)。常见的做法是什么?我应该将元组或列表存储在列表中吗?

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?


回答 0

sorted_by_second = sorted(data, key=lambda tup: tup[1])

要么:

data.sort(key=lambda tup: tup[1])  # sorts in place
sorted_by_second = sorted(data, key=lambda tup: tup[1])

or:

data.sort(key=lambda tup: tup[1])  # sorts in place

回答 1

from operator import itemgetter
data.sort(key=itemgetter(1))
from operator import itemgetter
data.sort(key=itemgetter(1))

回答 2

如果您想将数组从高到低排序,我只想添加到Stephen的答案中,除了上面的注释中的另一种方法就是将其添加到行中:

reverse = True

结果将如下所示:

data.sort(key=lambda tup: tup[1], reverse=True)

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)

回答 3

为了按照多个条件进行排序,例如按元组中的第二个和第三个元素进行排序,

data = [(1,2,3),(1,2,1),(1,1,4)]

并定义一个lambda来返回描述优先级的元组,例如

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

For sorting by multiple criteria, namely for instance by the second and third elements in a tuple, let

data = [(1,2,3),(1,2,1),(1,1,4)]

and so define a lambda that returns a tuple that describes priority, for instance

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

回答 4

斯蒂芬的答案就是我会用的答案。为了完整起见,这是带有列表推导的DSU(装饰-排序-取消装饰)模式:

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

或者,更简洁地说:

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

Python Sorting HowTo中所述,自Python 2.4启用关键功能以来,就没有必要这样做

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

为了对元组列表进行排序(<word>, <count>),以count降序和word字母顺序:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

我使用这种方法:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

它给了我结果:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

In order to sort a list of tuples (<word>, <count>), for count in descending order and word in alphabetical order:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

I use this method:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

and it gives me the result:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

回答 6

没有lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

Without lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

回答 7

itemgetter() 比…快一点 lambda tup: tup[1],但增长幅度相对较小(大约10%到25%)。

(IPython会话)

>>> 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

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

回答 8

@Stephen的答案很关键!这是一个更好的可视化示例,

为Ready Player One粉丝大喊大叫!=)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key是一个函数,将调用该函数来转换集合的项目以进行比较compareTo

传递给key的参数必须是可调用的。在这里,使用lambdacreate创建一个匿名函数(可调用)。
lambda的语法是单词lambda,后跟一个可迭代的名称,然后是单个代码块。

在下面的示例中,我们正在对元组列表进行排序,该元组列表包含某些事件和演员名称的信息记录时间。

我们按照事件发生的时间对该列表进行排序-这是元组的第0个元素。

注意- s.sort([cmp[, key[, reverse]]]) 将s的项目排序到位

@Stephen ‘s answer is to the point! Here is an example for better visualization,

Shout out for the Ready Player One fans! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key is a function that will be called to transform the collection’s items for comparison.. like compareTo method in Java.

The parameter passed to key must be something that is callable. Here, the use of lambda creates an anonymous function (which is a callable).
The syntax of lambda is the word lambda followed by a iterable name then a single block of code.

Below example, we are sorting a list of tuple that holds the info abt time of certain event and actor name.

We are sorting this list by time of event occurrence – which is the 0th element of a tuple.

Note – s.sort([cmp[, key[, reverse]]]) sorts the items of s in place


回答 9

对元组进行排序非常简单:

tuple(sorted(t))

Sorting a tuple is quite simple:

tuple(sorted(t))