2010-01-09 8 views
1

J'ai besoin de trier une liste de tuples par le premier élément dans l'ordre décroissant, puis par le second élément dans l'ordre croissant. Pour ce faire, j'ai implémenté la fonction suivante, mais je pense que cela pourrait être plus rapide.Optimiser la fonction pour trier une liste de tuples

>>> compare = lambda a, b: -cmp(b[1], a[1]) if b[0] == a[0] else cmp(b[0], a[0]) 
>>> sorted([(0, 2), (0, 1), (1, 0), (1, 2)], cmp=compare) 
[(1, 0), (1, 2), (0, 1), (0, 2)] 

Est-il possible de l'optimiser? Voir la comparaison avec la fonction intégrée:

>>> timeit.Timer(stmt='sorted([(int(random.getrandbits(4)),int(random.getrandbits(4))) for x in xrange(10)], cmp=compare)', setup='import random; compare=compare = lambda a, b: -cmp(b[1], a[1]) if b[0] == a[0] else cmp(b[0], a[0])').timeit(100000) 
4.0584850867917339 
>>> timeit.Timer(stmt='sorted([(int(random.getrandbits(4)),int(random.getrandbits(4))) for x in xrange(10)])', setup='import random').timeit(100000) 
2.6582965153393161 

Répondre

8

Pour moi, il est un peu plus rapide d'utiliser une clé au lieu d'une fonction de comparaison, et sans doute aussi plus facile à lire:

sorted([(0, 2), (0, 1), (1, 0), (1, 2)], key = lambda x:(-x[0], x[1])) 

Cette nécessite Python 2.4 ou plus récent.

+0

+1, vous me battez. Livré à mi-chemin entre les tests de timing de l'OP. – balpha

+0

+1 a ajouté une fin paren. – bernie

+0

Merci! C'est assez rapide pour moi :-) >>> timeit.Timer (stmt = 'trié ([(int (random.getrandbits (4)), int (random.getrandbits (4))) pour x dans xrange (10)], touche = lambda x: (- x [0], x [1])) ', setup =' import aléatoire; '). Timeit (100000) 3.2802747276537048 – jbochi

0

Comment cela se cumule-t-il pour vous?

compare = lambda a, b: cmp(b[0], a[0]) and cmp(a[1],b[1]) 
Questions connexes