J'ai un tas de listes de tri des objets et une fonction de comparaison Qu'est-ce que mais c'est assez inefficace. Meilleures réponses? P> p> magie code> ressemble? Ma mise en œuvre actuelle est p>
9 Réponses :
Je ne sais pas si ce serait plus rapide, mais vous pouvez le simplifier avec: Vous pouvez également utiliser CMP code> plutôt que
clé code> si vous préférez. p> p>
Utilisez le BISECT code>
module. À partir de la documentation: "Ce module permet de maintenir une liste dans la commande triée sans avoir à trier la liste après chaque insertion."
import bisect def magic(*args): r = [] for a in args: for i in a: bisect.insort(r, i) return r
Python Standard Library offre une méthode pour celui-ci: Cependant, je pense qu'il a la même complexité que votre propre solution, bien que L'utilisation des itérateurs devrait donner une très bonne optimisation et augmentation de la vitesse. P> p> heapht.merge < / code>
.
Comme indique la documentation, il est très similaire à utiliser iTertools (mais avec plus de limitations); Si vous ne pouvez pas vivre avec ces limitations (ou si vous n'utilisez pas Python 2.6), vous pouvez faire quelque chose comme ceci:
L'utilisation de la clé au lieu de CMP devrait être préférée (et devrait être plus rapide). Python3 n'a pas de paramètre CMP de toute façon.
En fait, j'utilisais simplement le même format que OP, mais vous avez absolument raison et clé i> devrait être préféré sur CMP i>.
Eh bien, et la fonction CMP de l'OP est fausse et ne fonctionne pas. Si vous utilisez du trempe, vous devrez fournir des méthodes LT B> etc. de votre classe ou d'utiliser un tuple de (clé de tri, objet) dans votre tas.
Je pense que tu veux dire itoTools.chain (* args). Ce que vous avez écrit est équivalent à trier (ITER (ARG), CMP), ce qui a peu de sens.
Si je comprends bien cela, le tri des listes concaténées est θ (n.log n) code> de complexité (solution proposée par exemple de code), mais la fusion (de tri) est
θ (n) < / code>. Pas si petite différence.
L'exemple de code doit être avec heapq.merge code>. Utiliser triés et iTerTools ensemble n'a pas beaucoup de sens. Il suffit d'écrire une fonction clé et d'utiliser
trié (a + b + c, clé = lambda x: x.points) code> pour une liste ou
heapq.merge (a, b, c, clé = Lambda x: x.points) code> pour un itérateur.
Au lieu d'utiliser une liste, vous pouvez utiliser un [tas] ( http: // en.wikipedia.org/wiki/heap_(Data_Structure) . P>
L'insertion est O (log (n)), de sorte que la fusion A, B et C sera O (n journal (n)) p>
en Python, vous pouvez utiliser le hePQ code> module a >. p>
+1: trier une liste de manière intrinsèquement inefficace: empêchez le tri en utilisant une structure plus intelligente.
@Organicpanda: Avez-vous lu la réponse? Il dit que heepq code> amortiise le coût de tri. C'est une structure plus intelligente. Considérez cela aussi. Accumuler trois collections distinctes semble stupide. Pourquoi ne pas accumuler un hachage d'objets mutables; Cela peut être mis à jour par des objets des autres sources. Maintenant, la "comparaison" est discutable car les objets sont tous associés correctement les uns aux autres sans aucun tri.
@ S.Lott Mes excuses - Je pensais que tu suggérais une réponse plus intelligente de votre propre mais pas l'expliquer .. mon mauvais
une solution d'une ligne utilisant trié: imo cette solution est très lisible. p> Utilisation du module de trempe, il pourrait être plus efficace, mais je ne l'ai pas testé . Vous ne pouvez pas spécifier la fonction CMP / Key dans HePQ, vous devez donc implémenter OBJ à trier implicitement. P> import heapq
def magic(*args):
h = []
for a in args:
heapq.heappush(h,a)
return [i for i in heapq.heappop(h)
Votre méthode de démaquillage est un gâchis. Vous poussez des listes entières au lieu de leurs articles et vous ignorez la clé. La doublure est cool, cependant.
Oui, vous avez raison, j'ai utilisé le trempe à quelques reprises et je ne colle pas de consoler pour la tester. Ma faute, désolé. Bien que maintenant, je vois que cet objet Obj doit être défini sur "triable" pour le travail de WePQ, car vous ne pouvez pas spécifier la fonction CMP / Key dans le trempe.
Ce code est tout autour d'un gâchis. Les deux extraits ont des erreurs de syntaxe et l'utilisation de la somme des listes de concaténation est très inefficace. Sans parler qu'il y a de l'opérateur.AtTrgeter à remplacer la Lambda.
Vous allez ici: un trier de fusion entièrement fonctionnel pour les listes (adapté de mon genre Ici ): appelez-le comme ceci: p> Pour faire bonne mesure, je vais jeter dans un couple des modifications apportées à votre classe OBJ: p>
auto code> à
__ init __ () code> li>
__ cmP __ code> une fonction membre li>
STR () code> Fonction de membre à présenter
obj code> comme chaîne li>
ul> p>
J'aime la réponse de Roberto Liffredo. Je ne savais pas sur HeaPq.Merge (). Hmmmph.
Voici à quoi ressemble la solution complète à l'aide de la tête de Roberto: p> ou: p>
J'ai posé une question similaire et j'ai obtenu d'excellentes réponses: p>
ci-dessous est un exemple d'une fonction qui fonctionne dans des comparaisons O (n).
Vous pouvez rendre cela plus rapide en faisant des hérisseurs A et B et en les incrémentant. P>
J'ai simplement appelé la fonction deux fois pour fusionner 3 listes: P>
def zip_sorted(a, b): ''' zips two iterables, assuming they are already sorted ''' i = 0 j = 0 result = [] while i < len(a) and j < len(b): if a[i] < b[j]: result.append(a[i]) i += 1 else: result.append(b[j]) j += 1 if i < len(a): result.extend(a[i:]) else: result.extend(b[j:]) return result def genSortedList(num,seed): result = [] for i in range(num): result.append(i*seed) return result if __name__ == '__main__': a = genSortedList(10000,2.0) b = genSortedList(6666,3.0) c = genSortedList(5000,4.0) d = zip_sorted(zip_sorted(a,b),c) print d
S'ils sont: Stackoverflow.com/Questtions/ 464342 / ...
Quelle est la taille de ces listes? Combien de temps est passé à les trier? Mesure avant (et après) que vous optimisez.