如何将附加参数传递给自定义 python 排序函数

Posted

技术标签:

【中文标题】如何将附加参数传递给自定义 python 排序函数【英文标题】:How to pass additional arguments to custom python sorting function 【发布时间】:2013-11-06 12:27:06 【问题描述】:

背景:

我想知道如何实现高级排序函数,我可以将它们作为元组元素传递给 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) ))

基本上我想实现上面描述的'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)

添加。详情:

    我用的是python 2.7 这个问题实际上是使用 Django 查询集而不是对象列表,但为了演示目的,我认为对象列表具有相同的目的。 此排序的目标是先按指定语言排序,然后返回 && 按照默认排序(在本例中为列表排序)对剩余项目进行排序。

问题:

如上所示,我怎样才能告诉“key”参数将额外参数“firstLanguage”&&“possibleLanguages”传递给自定义排序函数?

【问题讨论】:

lambda elem: sortByFirstLanguage(elem, firstLanguage)?这将从sorted() 调用它的元素中获取elem,并从定义它的位置获取firstLanguage 您没有希望以这种特殊方式传递它们,因为key 不是这样工作的。 key 必须采用在每个项目上调用的函数(或任何可调用的)并返回排序键。不过,您也许可以通过稍微不同的设计实现类似的效果。 使用 djangos 内置方法对查询集进行排序有什么问题?你需要sortedBookList 包含什么?按语言排序的书籍列表,首先列出某种语言? key 参数只接受 1 个函数,因此您必须编写一个函数来执行所有 3 种排序。 【参考方案1】:

正如 Ashish 在 cmets 中指出的那样,我们首先需要组合这些函数,因为 key 只接受单个函数。如果我们返回函数结果的序列 (list, tuple),Python 会做正确的事,如果前面的元素相等 (source),只会比较后面的(更右边的)元素。

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

使用 lambda:

sortedBookList = sorted(
    bookList, 
    key=lambda elem: (sortByName(elem), 
                      sortByFirstLanguage(elem, firstLanguage), 
                      sortByLanguages(elem, possibleLanguages)))

使用高阶函数:

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))

Lambda 对我来说似乎最干净,所以我可能会使用它。

【讨论】:

以上是关于如何将附加参数传递给自定义 python 排序函数的主要内容,如果未能解决你的问题,请参考以下文章

如何通过原始指针将闭包作为参数传递给 C 函数?

Laravel 将附加参数传递给函数

将附加参数传递给角度组件内的方法装饰器

如何将三个或多个参数传递给自定义模板标签过滤器 django?

Firebase 动态链接将自定义参数传递给 iOS 和 android

是否可以将自定义参数传递给setState回调函数?