Sort list of list with custom compare function in

2019-02-01 09:17发布

I know there are several questions named like this, but I can't seems to get their answers to work.

I have a list of lists, 50 times 5 elements. Now I want to sort this list by applying a custom compare function to each element. This function calculates the fitness of the list by which the elements shall be sorted. I created two functions, compare and fitness:

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

and

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

Then I tried to call them by:

sorted(mylist, cmp=compare)

or

sorted(mylist, key=fitness)

or

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

or

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

Also I tried list.sort() with the same parameters. But in any case the functions don't get a list as an argument but a None. I have no idea why that is, coming from mostly C++ this contradicts any idea of a callback function for me. How can I sort this lists with a custom function?

Edit I found my mistake. In the chain that creates the original list one function didn't return anything but the return value was used. Sorry for the bother

3条回答
走好不送
2楼-- · 2019-02-01 09:41

Also, your compare function is incorrect. It needs to return -1, 0, or 1, not a boolean as you have it. The correct compare function would be:

def compare(item1, item2):
    if fitness(item1) < fitness(item2):
        return -1
    elif fitness(item1) > fitness(item2):
        return 1
    else:
        return 0
查看更多
Anthone
3楼-- · 2019-02-01 09:46
>>> 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]]

The above works. Are you doing something different?

Notice that your key function is just sum; there's no need to write it explicitly.

查看更多
欢心
4楼-- · 2019-02-01 09:49

You need to slightly modify your compare function and use functools.cmp_to_key to pass it to sorted. Example code:

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

Output:

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

Works :)

查看更多
登录 后发表回答