Quali argomenti non funzione Python sort () hanno?
-
21-09-2019 - |
Domanda
C'è un altro argomento che key
, ad esempio: value
Soluzione
Argomenti sort
e sorted
Sia sort
e sorted
hanno tre argomenti chiave: cmp
, key
e 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
Utilizzando key
e reverse
è preferito, perché lavorano molto più veloce che un cmp
equivalente.
key
dovrebbe essere una funzione che prende un oggetto e restituisce un valore da confrontare e ordinare. reverse
permette di invertire l'ordinamento.
Uso argomento key
È possibile utilizzare operator.itemgetter
come un argomento chiave per ordinare per secondo, terzo elemento, ecc in una tupla.
Esempio
>>> 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')]
Spiegazione
Le sequenze possono contenere oggetti, neppure paragonabile, ma se possiamo definire una funzione che produce qualcosa che possiamo confrontare per ciascuno degli elementi, possiamo passare questa funzione in argomento key
a sort
o sorted
.
itemgetter
, in particolare, crea una tale funzione che recupera l'elemento data dal proprio operando. Un esempio dalla sua documentazione:
Dopo,
f=itemgetter(2)
, ilf(r)
chiamata restituiscer[2]
.
Mini-benchmark, key
vs cmp
Solo per curiosità, key
e prestazioni cmp
rispetto, più piccolo è meglio:
>>> 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
Quindi, l'ordinamento con key
sembra essere almeno due volte più veloce di smistamento con cmp
. Utilizzando itemgetter
invece di lambda x: x[1]
fa specie ancora più veloce.
Altri suggerimenti
Inoltre key=
, il metodo sort
delle liste in Python 2.x potrebbe in alternativa prendere un argomento cmp=
( non una buona idea, è stato rimosso in Python 3); con uno o nessuno di questi due, si può sempre passare reverse=True
di avere il tipo andare verso il basso (invece che verso l'alto come è il default, e che si può anche richiedere esplicitamente con reverse=False
se siete veramente interessati a farlo per qualche motivo) . Non ho idea di che cosa si suppone che l'argomento value
stai citano a fare.
Sì, ci vuole altri argomenti, ma non value
.
>>> print list.sort.__doc__
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
Cosa sarebbe un argomento value
anche significare?