12
votes

Fusionner des listes de tri en Python

J'ai un tas de listes de tri des objets et une fonction de comparaison xxx

Qu'est-ce que magie ressemble? Ma mise en œuvre actuelle est xxx

mais c'est assez inefficace. Meilleures réponses?


2 commentaires

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.


9 Réponses :


0
votes

Je ne sais pas si ce serait plus rapide, mais vous pouvez le simplifier avec: xxx

Vous pouvez également utiliser CMP plutôt que clé si vous préférez.


0 commentaires

2
votes

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


0 commentaires

13
votes

Python Standard Library offre une méthode pour celui-ci: 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: XXX

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.


6 commentaires

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é devrait être préféré sur CMP .


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 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) 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 . 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) pour une liste ou heapq.merge (a, b, c, clé = Lambda x: x.points) pour un itérateur.




0
votes

une solution d'une ligne utilisant trié: xxx pré>

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)


3 commentaires

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.



0
votes

Vous allez ici: un trier de fusion entièrement fonctionnel pour les listes (adapté de mon genre Ici ): xxx

appelez-le comme ceci: xxx

Pour faire bonne mesure, je vais jeter dans un couple des modifications apportées à votre classe OBJ: xxx

  • dérive de l'objet
  • pass auto à __ init __ ()
  • faire __ cmP __ une fonction membre
  • Ajouter un STR () Fonction de membre à présenter obj comme chaîne

0 commentaires

3
votes

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: xxx

ou: xxx


0 commentaires


0
votes

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


0 commentaires