按Python中的任意数量标准排序

时间:2017-02-02 04:16:48

标签: python sorting

假设我有一个数据表,我希望能够从按某些条件(如SQL)排序的表中返回数据。问题是,我不知道需要订购多少东西,ORDER BY命令后面只能跟一个列名,或者两个,或者100个。

我见过其他答案:

s = sorted(s, key = lambda x: (x[1], x[2]))

...但是tuple参数是硬编码的,不是在运行时创建的。我希望能够做到这样的事情:

# Build list of columns to sort by, in ascending order of priority
orderings = [0, 2, ...]
s = sorted(s, key = lambda x: orderings)

这可能吗?我还有其他选择吗?

4 个答案:

答案 0 :(得分:4)

一种简单的方法与您已有的方式类似:

s = sorted(s, key = lambda x: [x[i] for i in orderings])

否则你可以简单地排序多次。 Python排序是稳定的,这意味着任何比较相等的元素将保持其原始顺序。通过从最不重要的密钥到最重要的密钥进行多次排序,您将发现最终结果正是您所需要的。

答案 1 :(得分:3)

使用operator.itemgetter作为关键功能。

>>> import operator
>>> items = [1, 2, 4]
>>> key = operator.itemgetter(*items)
>>> key
operator.itemgetter(1, 2, 4)
>>> a = ['kljdfii', 'lkjfo', 'lklvjo']
>>> sorted(a, key = key)
['lkjfo', 'lklvjo', 'kljdfii']
>>> 

答案 2 :(得分:1)

这对dict个离子点很有意义,但这个方法类似于@wwii的答案(我使用键而不是列):

results = [{'name': 'Peter', 'score': 10, 'match': 0},
           {'name': 'Wendy', 'score': 2, 'match': 1},
           {'name': 'Hook', 'score': 1000, 'match': 0}]

from operator import itemgetter

orderby = ['match']  # define the keys by which to sort

sorted(results, key=itemgetter(*orderby))

给出:

[{'match': 0, 'name': 'Peter', 'score': 10},
 {'match': 0, 'name': 'Hook', 'score': 1000},
 {'match': 1, 'name': 'Wendy', 'score': 2}]

或:

orderby = ['match', 'name']

sorted(results, key=itemgetter(*orderby))

给出:

[{'match': 0, 'name': 'Hook', 'score': 1000},
 {'match': 0, 'name': 'Peter', 'score': 10},
 {'match': 1, 'name': 'Wendy', 'score': 2}]

答案 3 :(得分:0)

我将用纯python回答你的问题,然后告诉你如何用库解决问题。您可以继续,具体取决于哪种更适合您要做的事情。

纯Python

这里的问题是,在编写代码时,您不确定要排序的列,但仍需要创建要排序的元组。这就是上面的(x[1], x[2])正在做的事情。它选择第二列和第三列(索引1和2)作为要排序的列。你需要一种方法来做到这一点,而无需将整数1和2硬编码到代码中。

假设您有一个名为s的列表列表,并且您希望按这些列表中某些列的子集进行排序。

s = < a list of lists >
orderings = [ 1, 2 ] # Could come from user input, for example.
s = sorted(s, key = lambda elem: tuple(map(elem.__getitem__, orderings)))

事实证明,python中的索引实际上是用于调用__getitem__魔术方法的语法糖。通过将__getitem__映射到orderings中的每个索引,您可以创建要排序的键列表。然后,您可以使用tuples构造函数将它们动态转换为tuple。每行发生一次,基本上选择排序键。这正是sorted函数正在寻找的东西。

图书馆解决方案

在我看来,以这种方式对数据进行排序非常适合一次性工作,但很难阅读。在你的问题中,你假设你在python中有一个数据表,你想对它进行一些排序。处理这种情况的最佳方法是使用适当的库来处理表格数据。我建议pandas dataframe library。假设您的数据已经位于名为df的pandas数据框中,其中的列名为firstsecondthird。我们还假设您希望按first升序排序,然后按third降序排序。

df.sort_values(by=['first', 'third'], ascending=[True, False])

就是这样。此函数分别按升序和降序返回按first排序的新数据帧,然后是third。要做到这一点,您需要知道的是列的名称及其排序方向。它比处理元组和索引要清晰得多。缺点是pandas库有很多依赖,很难安装。