3

我是这里的python新手,我遇到了一个相当简单的问题——我正在寻找解决这个问题的最有效方法。所以,我有 5 个列表如下:

a,b,c,d,score

上面的列表都具有相同的大小(在我的情况下为 500)。a,b,c,d是字符串列表并且score是一个int列表。

我想做的是a,b,c,d基于score. 因此,我首先要score根据降序模式进行排序,然后a,b,c,d根据排序的分数列表(以相同的顺序)对相应的元素进行排序。

我正在考虑enumerate实现这一目标,但我想知道是否itertools可以在这里使用它来使其更快、更高效。

如果这是一个 101 问题,任何有关如何实现这一目标的指导将不胜感激&& 抱歉。

4

2 回答 2

6
sorted_lists = sorted(izip(a, b, c, d, score), reverse=True, key=lambda x: x[4])
a, b, c, d, score = [[x[i] for x in sorted_lists] for i in range(5)]

在这第一步中,zip将列表放在一起。这从每个列表中获取第一个元素并将它们放入一个元组中,将该元组附加到一个新列表中,然后对每个列表中的第二个元素执行相同的操作,依此类推。然后我们按第五个元素对这个元组列表进行排序(这是来自传递给key参数的匿名函数)。我们设置reverse=True为使列表降序。

在第二步中,我们使用一些嵌套列表推导和元组解包来拆分列表。我们创建了一个新的列表列表,其中每个内部列表是 中每个元组的所有第一个元素sorted_lists。您可以在如下一行中执行此操作,但我认为将其分成两部分可能会更清晰一些:

a, b, c, d, score = izip(*sorted(izip(a, b, c, d, score), reverse=True,
                         key=lambda x: x[4]))

这是一个返回元组列表的通用函数,其中元组是已排序的列表:

def sort_lists_by(lists, key_list=0, desc=False):
    return izip(*sorted(izip(*lists), reverse=desc,
                 key=lambda x: x[key_list]))
于 2013-03-25T09:03:10.663 回答
3

如果您正在进行大量数值工作或数组操作,则可能值得考虑使用numpy. 这个问题很容易用 numpy 数组解决:

In [1]: import numpy as np
In [2]: a = ['hi','hello']
In [3]: b = ['alice','bob']
In [4]: c = ['foo','bar']
In [5]: d = ['spam','eggs']
In [6]: score = [42,17]

从这里,以格式制作一个元组列表(a,b,c,d,score)并用 dtype 存储每个元组(str,str,str,str,int),您甚至可以给它们命名('a','b','c','d','score')以便以后访问它们:

In [7]: data = np.array(zip(a,b,c,d,score),
   ...:         dtype = [('a','S5'),('b','S5'),('c','S5'),('d','S5'),('score',int)]
   ...:     )

In [8]: data
Out[8]: 
array([('hi', 'alice', 'foo', 'spam', 42),
       ('hello', 'bob', 'bar', 'eggs', 17)], 
      dtype=[('a', 'S5'), ('b', 'S5'), ('c', 'S5'), ('d', 'S5'), ('score', '<i8')])

该数组的优点是您可以通过名称访问所有“列表”(字段):

In [9]: data['a']
Out[9]: 
array(['hi', 'hello'], 
      dtype='|S5')

In [10]: data['score']
Out[10]: array([42, 17])

要对它们进行排序,只需给出要排序的字段名称:

In [11]: sdata = np.sort(data, order='score')

In [12]: sdata
Out[12]: 
array([('hello', 'bob', 'bar', 'eggs', 17),
       ('hi', 'alice', 'foo', 'spam', 42)], 
      dtype=[('a', 'S5'), ('b', 'S5'), ('c', 'S5'), ('d', 'S5'), ('score', '<i8')])

In [13]: sdata['b']
Out[13]: 
array(['bob', 'alice'], 
      dtype='|S5')
于 2013-03-26T17:21:29.467 回答