对具有多个键且未知的列表列表进行排序 ascend/descend
Sort a list of lists with multiple keys and unknown ascend/descend
我正在尝试编写可以按未知数量的键对列表列表进行排序的代码,每个键都有一个关联的布尔值,对应于排序是升序还是降序。
我让它按升序或降序对所有键进行排序,如下所示:
import operator
def sort2D(table, *params):
table.sort(key=operator.itemgetter(*params), reverse = True)
return table
table = sort2D(table, *listOfKeys)
我也不确定如何将布尔值输入到该函数中。当我尝试为第二个输入列表执行类似代码时出现语法错误,如下所示:
import operator
def sort2D(table, *params, *args): #this is the line that causes the syntax error
table.sort(key=operator.itemgetter(*params), reverse = *args)
return table
table = sort2D(table, *listOfKeys, *listOfBools)
我知道这个错误是因为我误用了 *、*params 和 *args 将列表输入到函数中,但我不知道如何在没有看起来像的东西的情况下输入第二个列表类似于那个。是否可以将第二个列表输入到我拥有的函数中,或者我是否必须做一些完全不同的事情来完成我想要的?
编辑:我想要的输入和输出的示例如下所示:
['Smith', 'Bob', 4, 3.75, 'Blue']
['Jones', 'Tom', 17, 0.44, 'Blue']
['Smith', 'John', 3, 2.22, 'Yellow']
['Jones', 'Drew', 5, 6.74, 'Red']
如果按姓氏降序排序,然后按整数升序排序,则params 为[0, 2] 对应列,bools 为[True, False]。输出将如下所示:
['Smith', 'John', 3, 2.22, 'Yellow']
['Smith', 'Bob', 4, 3.75, 'Blue']
['Jones', 'Drew', 5, 6.74, 'Red']
['Jones', 'Tom', 17, 0.44, 'Blue']
一个函数不能有两个 *something
参数。无论如何,您也不能将多个 reverse=
值应用于单个 sort
调用。
唯一干净、完全通用的使用多个 reverse
值的方法(不知道可能被反转的键是否是字符串、数字、元组......),不幸的是,做多个 sort
通过(相反:最重要的键必须是您最后排序的键)。
所以...:[=22=]
def sort2D(table, params, reverses):
for parm, rev in reversed(zip(params, reverses)):
table.sort(key=operator.itemgetter(parm), reverse=rev)
return table
table = sort2D(table, listOfKeys, listOfBools)
如果您确实了解您正在排序的键(项目),例如它们都是数字,您可以 准备一个 key
函数,然后进行单次排序(将符号更改为对应于相应反转布尔值的真值的数字)。
但这对于通用键来说是一个非常具有挑战性的问题 -- 例如,我什至想不出一种有效地解决元组问题的方法!-)
即使只针对字符串做这件事,我认为至少也是一个 Google 面试级别的问题——“定义一个函数 rev
这样,对于 any 两个字符串 s1
和 s2
,
rev(s1) < rev(s2) if and only if s1 > s2
"""
(实际上,在这个完全通用的公式中,它比我记下它时想象的要难...!-)
在现实生活中,面对如此棘手的问题,我会进行多次 sort
传球,宣布胜利,然后回家:-)
我正在尝试编写可以按未知数量的键对列表列表进行排序的代码,每个键都有一个关联的布尔值,对应于排序是升序还是降序。
我让它按升序或降序对所有键进行排序,如下所示:
import operator
def sort2D(table, *params):
table.sort(key=operator.itemgetter(*params), reverse = True)
return table
table = sort2D(table, *listOfKeys)
我也不确定如何将布尔值输入到该函数中。当我尝试为第二个输入列表执行类似代码时出现语法错误,如下所示:
import operator
def sort2D(table, *params, *args): #this is the line that causes the syntax error
table.sort(key=operator.itemgetter(*params), reverse = *args)
return table
table = sort2D(table, *listOfKeys, *listOfBools)
我知道这个错误是因为我误用了 *、*params 和 *args 将列表输入到函数中,但我不知道如何在没有看起来像的东西的情况下输入第二个列表类似于那个。是否可以将第二个列表输入到我拥有的函数中,或者我是否必须做一些完全不同的事情来完成我想要的?
编辑:我想要的输入和输出的示例如下所示:
['Smith', 'Bob', 4, 3.75, 'Blue']
['Jones', 'Tom', 17, 0.44, 'Blue']
['Smith', 'John', 3, 2.22, 'Yellow']
['Jones', 'Drew', 5, 6.74, 'Red']
如果按姓氏降序排序,然后按整数升序排序,则params 为[0, 2] 对应列,bools 为[True, False]。输出将如下所示:
['Smith', 'John', 3, 2.22, 'Yellow']
['Smith', 'Bob', 4, 3.75, 'Blue']
['Jones', 'Drew', 5, 6.74, 'Red']
['Jones', 'Tom', 17, 0.44, 'Blue']
一个函数不能有两个 *something
参数。无论如何,您也不能将多个 reverse=
值应用于单个 sort
调用。
唯一干净、完全通用的使用多个 reverse
值的方法(不知道可能被反转的键是否是字符串、数字、元组......),不幸的是,做多个 sort
通过(相反:最重要的键必须是您最后排序的键)。
所以...:[=22=]
def sort2D(table, params, reverses):
for parm, rev in reversed(zip(params, reverses)):
table.sort(key=operator.itemgetter(parm), reverse=rev)
return table
table = sort2D(table, listOfKeys, listOfBools)
如果您确实了解您正在排序的键(项目),例如它们都是数字,您可以 准备一个 key
函数,然后进行单次排序(将符号更改为对应于相应反转布尔值的真值的数字)。
但这对于通用键来说是一个非常具有挑战性的问题 -- 例如,我什至想不出一种有效地解决元组问题的方法!-)
即使只针对字符串做这件事,我认为至少也是一个 Google 面试级别的问题——“定义一个函数 rev
这样,对于 any 两个字符串 s1
和 s2
,
rev(s1) < rev(s2) if and only if s1 > s2
"""
(实际上,在这个完全通用的公式中,它比我记下它时想象的要难...!-)
在现实生活中,面对如此棘手的问题,我会进行多次 sort
传球,宣布胜利,然后回家:-)