如何传递其他参数到自定义python排序函数 [英] How to pass additional arguments to custom python sorting function
问题描述
背景:
我想知道如何实现高级排序功能,我可以传递为tuple元素到pythonsorted的关键参数
以下是一个描述我想做的事情的例子:
class Book
def __init __(self,name,author,language,cost):
self.name = name
self.author = author
self.language = language
self.cost = cost
bookList = [书籍列表]
firstLanguage =亚美尼亚
可能的语言= [英语,西班牙语,亚美尼亚语,法语,汉语,斯瓦希里语]
possibleLanguages.remove(亚美尼亚)
sortedBookList = (bookList,key =(sortByName,sortByFirstLanguage(firstLanguage),
sortByLanguages(possibleLanguages)
)
)
基本上我想实现'sortByFirstLanguage'&& 'sortByLanguages'函数,以便我可以将它们作为'key'参数的元组项传递给python'sorted'函数。以下是一些关于自定义排序函数应该如何的示例代码:
def sortByName(elem):
return elem.name
def sortByFirstLanguage(elem,firstLanguage):
如果elem.language == firstLanguage:
return 1
else:
return -1
def sortByLanguages(elem,possibleLanguages):
如果elem.language in possibleLanguages:
return possibleLanguages.index(elem.language)
Addt。详细信息:
- 我正在使用python 2.7
- 这个问题实际上是使用Django查询而不是列表的对象,但为了表明目的,我认为一个对象的列表也是一样的。
- 这个排序的目的是首先用指定的语言进行排序,然后返回& &安培;按照默认顺序对其余项目进行排序(在本例中为列表排序)。
问题:
我怎么能告诉'key'参数传递额外的参数'firstLanguage'&& 可能的语言定制排序功能,如上所示?
正如Ashish在评论中指出的那样,组合这些功能,因为 key
只接受一个函数。如果我们返回一个函数结果的序列(list,tuple),Python将会做正确的事情,只要比较后面的(更右边的)元素,如果先前的元素是相等的(源)。
我知道有几种方法来做到这一点。
使用lambdas:
sortedBookList = sorted(
bookList,
key = lambda elem:(sortByName(elem),
sortByFirstLanguage(elem,firstLanguage),
sortByLanguages(elem,possibleLanguages))
使用高阶函数:
def key_combiner(* keyfuncs):$
$ b def sortByFirstLanguage(firstLanguage):
def helper(elem):
return [keyfunc(elem)for keyfunc in keyfuncs] (elem):
return elem.language == firstLanguage#True>
如果elem.language in possibleLanguages:
return possibleLanguages.index(可能的语言):
def帮助器(elem):
(elem.language)
return helper
sortedBookList = sorted(bookList,
key = key_combiner(sortByName,
sortByFirstLanguage(firstLanguage),
sortByLanguages可能的语言))
Lambdas对我来说似乎最干净,所以这可能是我会使用的。 >
Background:
I would like to know how I can implement advanced sorting functions that I can pass in as tuple element to the key argument of the python 'sorted' function.
Here is an example depicting what I would like to do:
class Book:
def __init__(self, name, author, language, cost):
self.name = name
self.author = author
self.language=language
self.cost = cost
bookList = [list of books]
firstLanguage = "Armenian"
possibleLanguages = ["English", "Spanish", "Armenian", "French", "Chinese", "Swahili"]
possibleLanguages.remove("Armenian")
sortedBookList = sorted(bookList, key=( sortByName, sortByFirstLanguage(firstLanguage),
sortByLanguages(possibleLanguages)
)
)
Basically I would like to implement the 'sortByFirstLanguage' && 'sortByLanguages' functions described above so that I can pass them to the python 'sorted' function as the tuple items of the 'key' argument. Here is some example code regarding what the custom sort functions should look like:
def sortByName(elem):
return elem.name
def sortByFirstLanguage(elem, firstLanguage):
if elem.language == firstLanguage:
return 1
else:
return -1
def sortByLanguages(elem, possibleLanguages):
if elem.language in possibleLanguages:
return possibleLanguages.index(elem.language)
Addt. Details:
- I am using python 2.7
- This problem is actually using Django querysets rather than lists of objects, but for demonstration of purpose, I think a list of objects serves the same purpose.
- The goal of this sorting is to sort by a specified language first, then go back && sort the remaining items by their default ordering (list ordering in this case).
Question:
How exactly can I tell the 'key' argument to pass in the extra arguments 'firstLanguage' && 'possibleLanguages' to custom sorting functions as I have shown above?
As Ashish points out in the comments, we first need to combine these functions, since key
only accepts a single functions. If we return a sequence (list, tuple) of the function results, Python will do the right thing, only comparing later (farther right) elements if the earlier elements are equal (source).
I know of a couple ways to do this.
Using lambdas:
sortedBookList = sorted(
bookList,
key=lambda elem: (sortByName(elem),
sortByFirstLanguage(elem, firstLanguage),
sortByLanguages(elem, possibleLanguages)))
Using higher-order functions:
def key_combiner(*keyfuncs):
def helper(elem):
return [keyfunc(elem) for keyfunc in keyfuncs]
return helper
def sortByFirstLanguage(firstLanguage):
def helper(elem):
return elem.language == firstLanguage # True > False
return helper
def sortByLanguages(possibleLanguages):
def helper(elem):
if elem.language in possibleLanguages:
return possibleLanguages.index(elem.language)
return helper
sortedBookList = sorted(bookList,
key=key_combiner(sortByName,
sortByFirstLanguage(firstLanguage),
sortByLanguages(possibleLanguages))
Lambdas seem cleanest to me, so that's probably what I'd use.
这篇关于如何传递其他参数到自定义python排序函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!