如何将其他参数传递给自定义python排序函数

Buc*_*uck 9 python sorting django django-queryset python-2.7

背景:

我想知道如何实现高级排序函数,我可以将它作为元组元素传递给python'sorted'函数的key参数.

这是一个描述我想做的事情的例子:

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) ))
Run Code Online (Sandbox Code Playgroud)

基本上我想实现上面描述的'sortByFirstLanguage'和'sortByLanguages'函数,这样我就可以将它们作为'key'参数的元组项传递给python'sorted'函数.下面是一些关于自定义排序函数应该是什么样子的示例代码:

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)
Run Code Online (Sandbox Code Playgroud)

ADDT.细节:

  1. 我正在使用python 2.7
  2. 这个问题实际上是使用Django查询集而不是对象列表,但为了演示目的,我认为对象列表具有相同的用途.
  3. 此排序的目标是首先按指定的语言排序,然后返回&&按其默认排序(在这种情况下为列表排序)对剩余项目进行排序.

题:

我如何告诉'key'参数将额外的参数'firstLanguage'&&'possibleLanguages'传递给自定义排序函数,如上所示?

Sam*_*ann 5

正如Ashish在评论中指出的那样,由于key仅接受单个功能,因此我们首先需要组合这些功能。如果我们返回函数结果的序列(列表,元组),Python将做正确的事情,只有在较早的元素相等时才比较较晚的元素()。

我知道有几种方法可以做到这一点。

使用lambda:

sortedBookList = sorted(
    bookList, 
    key=lambda elem: (sortByName(elem), 
                      sortByFirstLanguage(elem, firstLanguage), 
                      sortByLanguages(elem, possibleLanguages)))
Run Code Online (Sandbox Code Playgroud)

使用高阶函数:

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))
Run Code Online (Sandbox Code Playgroud)

Lambda对我来说似乎是最干净的,所以这可能就是我要使用的。