Tri liste de liste avec fonction de comparaison personnalisée en Python
je sais qu'il y a plusieurs questions nommées comme celle-ci, mais je n'arrive pas à obtenir leurs réponses pour travailler.
j'ai une liste de listes, 50 fois 5 éléments. Maintenant je veux trier cette liste en appliquant une fonction de comparaison personnalisée à chaque élément. Cette fonction calcule l'adéquation de la liste par laquelle les éléments doivent être triés. J'ai créé deux fonctions, de comparer et de remise en forme:
def compare(item1, item2):
return (fitness(item1) < fitness(item2))
et
def fitness(item):
return item[0]+item[1]+item[2]+item[3]+item[4]
Puis j'ai essayé de les appeler par:
sorted(mylist, cmp=compare)
ou
sorted(mylist, key=fitness)
ou
sorted(mylist, cmp=compare, key=fitness)
ou
sorted(mylist, cmp=lambda x,y: compare(x,y))
J'ai aussi essayé list.sort() avec les mêmes paramètres. Mais dans tous les cas les fonctions ne reçoivent pas une liste comme argument mais un None
. Je n'ai aucune idée de la raison pour laquelle c'est, venant principalement de C++ cela contredit toute idée d'une fonction de rappel pour moi. Comment puis-je trier ces listes avec une fonction personnalisée?
Modifier J'ai trouvé mon erreur. Dans la chaîne qui crée le la première fonction list one ne retournait rien mais la valeur de retour était utilisée. Désolé pour la peine
3 réponses
>>> 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]]
Les travaux ci-dessus. Faites-vous quelque chose de différent?
notez que votre fonction clé est juste sum
; il n'est pas nécessaire de l'écrire explicitement.
de plus, votre fonction de comparaison est incorrecte. Il doit retourner -1, 0, ou 1, pas une valeur booléenne que vous l'avez. La bonne comparaison serait:
def compare(item1, item2):
if fitness(item1) < fitness(item2):
return -1
elif fitness(item1) > fitness(item2):
return 1
else:
return 0
vous devez modifier légèrement votre compare
fonction et utilisation functools.cmp_to_key
pour passer à sorted
. Exemple de 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))
Sortie:
[[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]]
Fonctionne :)