使用自定义比较功能对列表列表进行排序

问题描述 投票:58回答:4

我知道有几个这样的问题,但它们似乎对我不起作用。

我有一个列表列表,是50个元素的5倍。我想通过对每个元素应用自定义比较功能来对该列表进行排序。此函数计算元素排序所依据的列表的适用性。我创建了两个函数,比较和适应性:

def compare(item1, item2):
    return (fitness(item1) < fitness(item2))

def fitness(item):
    return item[0]+item[1]+item[2]+item[3]+item[4]

然后我尝试通过以下方式致电给他们:

sorted(mylist, cmp=compare)

sorted(mylist, key=fitness)

sorted(mylist, cmp=compare, key=fitness)

sorted(mylist, cmp=lambda x,y: compare(x,y))

[我也尝试使用相同的参数进行list.sort()。但是无论如何,函数都不会获得列表作为参数,而是获得None。我不知道为什么,这主要来自C ++,这与我对回调函数的任何想法相矛盾。如何使用自定义函数对列表进行排序?

编辑我发现了我的错误。在创建原始列表的链中,一个函数未返回任何内容,但使用了返回值。对不起,麻烦

python list sorting callback
4个回答
28
投票
>>> l = [list(range(i, i+4)) for i in range(10,1,-1)]
>>> l
[[10, 11, 12, 13], [9, 10, 11, 12], [8, 9, 10, 11], [7, 8, 9, 10], [6, 7, 8, 9], [5, 6, 7, 8], [4, 5, 6, 7], [3, 4, 5, 6], [2, 3, 4, 5]]
>>> sorted(l, key=sum)
[[2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9, 10], [8, 9, 10, 11], [9, 10, 11, 12], [10, 11, 12, 13]]

以上作品。您在做其他事情吗?

注意,您的按键功能仅为sum;无需显式编写。


65
投票

而且,您的比较功能不正确。它需要返回-1、0或1,而不是您所需要的布尔值。正确的比较功能为:

def compare(item1, item2):
    if fitness(item1) < fitness(item2):
        return -1
    elif fitness(item1) > fitness(item2):
        return 1
    else:
        return 0

17
投票

您需要稍微修改compare功能,然后使用functools.cmp_to_key将其传递给sorted。示例代码:

import functools

lst = [list(range(i, i+5)) for i in range(5, 1, -1)]

def fitness(item):
    return item[0]+item[1]+item[2]+item[3]+item[4]
def compare(item1, item2):
    return fitness(item1) - fitness(item2)

sorted(lst, key=functools.cmp_to_key(compare))

输出:

[[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]]

Works:)


10
投票

由于OP要求使用自定义比较功能(这也是导致我提出这个问题的原因,所以我想在这里给出可靠的答案:

通常,您想使用内置的sorted()函数,该函数将自定义比较器作为其参数。我们需要注意以下事实:在Python 3中,参数名称和语义已更改。

自定义比较器的工作方式

[提供自定义比较器时,通常应返回遵循以下模式的整数/浮点值(与大多数其他编程语言和框架一样):

  • 当左项目应排序时返回一个负值(< 0右]时应将其排序
  • 应该对左项进行排序时返回正值(> 0之后
  • 右项
  • 当左项和右项都具有相同的权重并且应“相等”排序而没有优先权时返回0
  • 在OP的特定情况下,可以使用以下自定义比较功能:

def compare(item1, item2):
    return fitness(item1) - fitness(item2)

使用减号运算是一个不错的技巧,因为当左item1的权重大于右item2的权重时,它会产生正值。因此,item1将被排序为[[after

item2如果要颠倒排序顺序,只需颠倒减法:return fitness(item2) - fitness(item1)

在Python 2中调用sorted()

sorted(mylist, key=cmp(compare))

或:

sorted(mylist, cmp=lambda item1, item2: fitness(item1) - fitness(item2))

在Python 3中调用sorted()

from functools import cmp_to_key sorted(mylist, key=cmp_to_key(compare))

或:

from functools import cmp_to_key sorted(mylist, key=cmp_to_key(lambda item1, item2: fitness(item1) - fitness(item2)))

© www.soinside.com 2019 - 2024. All rights reserved.