Question

Y at-il autre argument que key, par exemple: value

?
Était-ce utile?

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), le f(r) d'appel retourne r[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?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top