Quels arguments ne fonction de tri Python () ont?
-
21-09-2019 - |
Question
Y at-il autre argument que key
, par exemple: value
La solution
Arguments des sort
et sorted
Les deux sort
et sorted
ont trois arguments clés: cmp
, key
et reverse
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
Utilisation key
et reverse
est préférable, parce qu'ils travaillent beaucoup plus rapide qu'un cmp
équivalent.
key
doit être une fonction qui prend un objet et renvoie une valeur à comparer et trier. reverse
permet d'inverser l'ordre de tri.
Utilisation argument key
Vous pouvez utiliser operator.itemgetter
comme argument clé pour trier par seconde, troisième élément, etc. dans un tuple.
Exemple
>>> from operator import itemgetter
>>> a = range(5)
>>> b = a[::-1]
>>> c = map(lambda x: chr(((x+3)%5)+97), a)
>>> sequence = zip(a,b,c)
# sort by first item in a tuple
>>> sorted(sequence, key = itemgetter(0))
[(0, 4, 'd'), (1, 3, 'e'), (2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c')]
# sort by second item in a tuple
>>> sorted(sequence, key = itemgetter(1))
[(4, 0, 'c'), (3, 1, 'b'), (2, 2, 'a'), (1, 3, 'e'), (0, 4, 'd')]
# sort by third item in a tuple
>>> sorted(sequence, key = itemgetter(2))
[(2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c'), (0, 4, 'd'), (1, 3, 'e')]
Explication
Les séquences peuvent contenir des objets, même pas comparable, mais si nous pouvons définir une fonction qui produit quelque chose que nous pouvons comparer pour chacun des éléments, nous pouvons passer cette fonction dans argument key
à sort
ou sorted
.
itemgetter
, en particulier, crée une telle fonction qui va chercher l'élément donné de son opérande. Un exemple de sa documentation:
Après,
f=itemgetter(2)
, lef(r)
d'appel retourner[2]
.
Mini-référence, key
vs cmp
Juste par curiosité, key
et performance par rapport cmp
, plus petit est mieux:
>>> from timeit import Timer
>>> Timer(stmt="sorted(xs,key=itemgetter(1))",setup="from operator import itemgetter;xs=range(100);xs=zip(xs,xs);").timeit(300000)
6.7079150676727295
>>> Timer(stmt="sorted(xs,key=lambda x:x[1])",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
11.609490871429443
>>> Timer(stmt="sorted(xs,cmp=lambda a,b: cmp(a[1],b[1]))",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
22.335839986801147
Ainsi, le tri avec key
semble être au moins deux fois plus rapide que le tri avec cmp
. L'utilisation itemgetter
au lieu de lambda x: x[1]
fait sorte encore plus vite.
Autres conseils
En plus key=
, la méthode sort
des listes en Python 2.x pourrait également prendre un argument cmp=
( pas une bonne idée, il a été retiré en Python 3); soit avec ou aucun de ces deux, vous pouvez toujours passer reverse=True
d'avoir le genre aller vers le bas (au lieu de vers le haut comme par défaut, et que vous pouvez également demander explicitement reverse=False
si vous êtes vraiment envie de le faire pour une raison quelconque) . Je ne sais pas ce que cet argument de value
vous mentionnez est censé faire.
Oui, il faut d'autres arguments, mais pas value
.
>>> print list.sort.__doc__
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
Que serait un argument value
même dire?