如何传递其他参数到自定义python排序函数 [英] How to pass additional arguments to custom python sorting function

查看:141
本文介绍了如何传递其他参数到自定义python排序函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:



我想知道如何实现高级排序功能,我可以传递为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。详细信息:




  1. 我正在使用python 2.7

  2. 这个问题实际上是使用Django查询而不是列表的对象,但为了表明目的,我认为一个对象的列表也是一样的。

  3. 这个排序的目的是首先用指定的语言进行排序,然后返回& &安培;按照默认顺序对其余项目进行排序(在本例中为列表排序)。



问题:



我怎么能告诉'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:

  1. I am using python 2.7
  2. 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.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆