在Python中按任意数量的条件排序

在Python中按任意数量的条件排序,python,sorting,Python,Sorting,假设我有一个数据表,我希望能够从表中返回按某些条件排序的数据(如SQL)。问题是,我不知道我需要按多少进行排序,而orderby命令后面可能只跟一个列名、两个列名或100个列名 我已经看到其他答案可以做到这一点: s = sorted(s, key = lambda x: (x[1], x[2])) …但是元组参数是硬编码的,不是在运行时创建的。我希望能够做到以下几点: # Build list of columns to sort by, in ascending order of prio

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

我已经看到其他答案可以做到这一点:

s = sorted(s, key = lambda x: (x[1], x[2]))
…但是元组参数是硬编码的,不是在运行时创建的。我希望能够做到以下几点:

# Build list of columns to sort by, in ascending order of priority
orderings = [0, 2, ...]
s = sorted(s, key = lambda x: orderings)
可能吗?我还有哪些其他选项?

用于按键功能

>>> 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']
>>> 
用于键功能

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

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

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

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

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

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

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

这对于
dict
字典来说最有意义,但方法类似于
@wwii
的答案(我使用的是键而不是列):

给出:

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

其中:

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

这在
dict
词典中最有意义,但方法类似于
@wwii
的答案(我使用的是键而不是列):

给出:

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

其中:

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

我将用纯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)))

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

我将用纯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)))

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

使用一些排序技术@GWW问题中明确指出了该链接的首要答案,因此我认为这还不够充分。这不仅仅是关于多把钥匙,而是关于不同数量的钥匙。@MarkRansom:我明白为什么它没有涵盖它。我收回了我的投票。使用一些排序技术@GWW问题中明确指出了该链接的首要答案,因此我认为这还不够充分。这不仅仅是关于多把钥匙,而是关于不同数量的钥匙。@MarkRansom:我明白为什么它没有涵盖它。我撤回了我的投票。