IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Remplissage de LISTE à partir de DICO.Temps de calcul explose !


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Par défaut Remplissage de LISTE à partir de DICO.Temps de calcul explose !
    Développeurs, Bonjour !

    Python codé par un mécanicien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        # VertexList = [ {'X':10, 'Y':10, 'VertexId':103}, {...} ... ]      LISTE DE DICTIONNAIRES
        # VertexListList = []
     
        i = 1
        while ( i <= len ( VertexList ) ) :
            VertexListList.append ( next ( ( [ item ['X'], item ['Y'] ] for item in VertexList if item ['VertexId'] == i ) ) )
            i = i + 1
    J'ordonne donc une liste par recherche de la clef 'VertexId' de ses éléments (des dicos).

    Cette boucle explose en temps de calcul, environ 1mn pour seulement 25000 dictionnaires dans la liste.

    Y a-t-il une méthode plus rapide que celle-là en temps de calcul ?

    Merci !
    SF

  2. #2
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Salut

    Citation Envoyé par santaflam Voir le message
    Y a-t-il une méthode plus rapide que celle-là en temps de calcul ?
    oh que oui ! Tout bêtement en utilisant la méthode sort :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    >>> import random
    >>> from time import time
    >>> 
    >>> idents = range(25000)
    >>> random.shuffle(idents)
    >>> # petite verif
    ... print idents[:10]
    [20527, 3454, 14104, 12341, 23876, 15896, 16088, 11081, 4679, 24899]
    >>> 
    >>> VertexList = [ {'X':0., 'Y':0., 'VertexId':i } for i in idents ] 
    >>> 
    >>> t0=time(); VertexList.sort(key=lambda elt: elt['VertexId']);time()-t0 
    0.0328829288482666
    >>> 
    >>> # autre verif
    ... import pprint
    >>> pprint.pprint(VertexList[:10])
    [{'VertexId': 0, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 1, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 2, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 3, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 4, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 5, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 6, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 7, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 8, 'X': 0.0, 'Y': 0.0},
     {'VertexId': 9, 'X': 0.0, 'Y': 0.0}]

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il y a au moins 2 choses qui sont chères en temps:

    - le while qui nécessite de calculer à chaque boucle len(...) alors que cette longueur ne change pas.

    - le if item ['VertexId'] == i qui nécessitera de parcourir la liste 25000 fois

    Si j'ai bien compris l'objectif, c'est de faire une liste des [x, y] pris dans l'ordre des valeurs des clés 'VertexId'.

    Dans ce cas, il est préférable de mettre les dico dans l'ordre de ces valeurs par un simple tri de la liste VertexList (les tris en Python sont très rapides).

    Puis de construire la nouvelle liste par une simple "compréhension de liste":

    Voilà ma proposition:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # tri de la liste pour avoir les dicos dans le bon ordre
    VertexList.sort(key=lambda v: v['VertexId'])
    # construction de la nouvelle liste des [x, y]
    VertexListList = [[dico['X'], dico['Y']]  for dico in VertexList]
    Essaie et donne le temps que tu obtiens!

    [grillé par plxpy]

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Les choses seraient peut être plus simple si VextexList était construite de sorte à ce que VextexList[id] = VextexList[id]['VertexId'], ou soit un dict dont la clé soit 'VertexId'.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre confirmé
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Par défaut
    Merci pour vos réponses respectives !

    Je peux me contenter du nouveau temps de calcul, néanmoins j'ai fait la comparaison suivante :

    1.
    Votre solution ( sort et réecriture de la liste ):
    Temps 0,2344 s
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        VertexList.sort ( key=lambda elt: elt['VertexId'] )
        VertexListList = [ [ item ['X'], item ['Y'] ] for item in VertexList ]
    2.
    Et une autre solution, basique, une itération et un test sur la clef:
    Temps 0,2031 s
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        i=1
        for item in VertexList :
            if item ['VertexId'] == i :
                VertexListList.append ( [ item ['X'], item ['Y'] ] )
            i=i+1
    N'est-ce pas curieux que cette 2ième méthode soit plus rapide (0,2031 contre 0,2344 s) , bien que paraissant assez loourde, par le if qui itère sur toute la liste ?


    @wiztricks:
    A sa construction la liste de départ Vertexlist est ordonnée effectivement. Mais elle est sujette à modification ultérieurement, voilà pourquoi la nécessité d'un "sort".

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    A mon avis, le 2ème code ne donne le bon résultat que si le tri est déjà fait! Sinon, la liste finale est incomplète.

    Et si la 1ère liste est déjà triée, il faut retirer le "sort" du 1er code pour comparer les temps de calcul.

    Cependant, j'ai déjà remarqué que les "compréhensions de liste" sont plus concises mais pas forcément plus rapides que les boucles classiques.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par santaflam Voir le message
    @wiztricks:
    A sa construction la liste de départ Vertexlist est ordonnée effectivement. Mais elle est sujette à modification ultérieurement, voilà pourquoi la nécessité d'un "sort".
    Si l'ordre des éléments dans la liste a quelque importance, pourquoi le changer par la suite?
    De plus, si vous vous efforciez de préserver l'ordre, plus besoin d'un dict contenant le VextexId - {'X':0., 'Y':0., 'VertexId':i } - puisque VextexList[id] = VextexList[id]['VertexId'] serait toujours vrai.
    note: virer VertexId, vous obligerait aussi à préserver l'ordre
    Enfin, si les performances vous inquiètent - ce que je comprend tout à fait à cause du nombre d'éléments - pourquoi ne pas construire une liste ordonnée de listes(ou de tuples) de coordonnées? Dans ce cas, l'opération que vous êtes en train de faire i.e. construire la liste des coordonnées serait déjà faite.

    Tout çà pour dire que si l'organisation initiale de vos données et le choix des structures n'est pas adapté, il faut peut être en changer. Et avec un langage comme Python "changer" n'est pas si compliqué...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre confirmé
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Par défaut
    Merci !

    Tyrtamos, exact pour la nécessité du "sort".

    Citation Envoyé par wiztricks Voir le message
    Si l'ordre des éléments dans la liste a quelque importance, pourquoi le changer par la suite?
    De plus, si vous vous efforciez de préserver l'ordre, plus besoin d'un dict contenant le VextexId - {'X':0., 'Y':0., 'VertexId':i } - puisque VextexList[id] = VextexList[id]['VertexId'] serait toujours vrai.
    note: virer VertexId, vous obligerait aussi à préserver l'ordre
    Enfin, si les performances vous inquiètent - ce que je comprend tout à fait à cause du nombre d'éléments - pourquoi ne pas construire une liste ordonnée de listes(ou de tuples) de coordonnées? Dans ce cas, l'opération que vous êtes en train de faire i.e. construire la liste des coordonnées serait déjà faite.
    ...
    - W
    J'ai introduit des dicos parce que je voulais être sûr de ne pas prendre une vitesse pour une coordonnée par exemple.
    Je dois construire un enregistrement de points avec leurs attributs respectifs: X(coord), Y(coord), V(vitesse), P (oids), VertexId etc
    L'ordre importe parce qu'il me faut relier ces points sur un graphique.
    L'ordre est muable parce que je peux effacer un point du graphique et le remplacer par une série de points.
    J'ai bien compris que si j'ordonne la liste alors:
    "VextexList[id] = VextexList[id]['VertexId'] serait toujours vrai."

    Une liste de listes aurait donc l'avantage d'être plus rapide, si j'ai bien compris ?

    Remarque indépendante:
    C'était assez pratique de faire comme suit: s'il trouve une des clefs dans le premier champ de l'enregistrement field, il actualise cette clef ...
    Assez cours comme écriture, au lieu de if field [0]=X, puis if field[0]=Y etc ... dans le cas où je passe par des listes. Mais ceci n'affecte pas le temps de calcul je pense ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    # field = enregistrement lu dans fichier texte
    Vertx = {'X':10, 'Y':10, 'V':800.0, 'VertexId':103} etc }
    if field [0] in Vertx :
        Vertx [ field [0] ] = float ( field [1:] )

Discussions similaires

  1. [Débutant] Temps de remplissage de liste différent selon l'appel
    Par 105rn2 dans le forum VB.NET
    Réponses: 6
    Dernier message: 05/09/2013, 19h28
  2. Remplissage feuille excel à partir d'un dbGrid
    Par izidor dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 22/02/2006, 18h09
  3. Réponses: 3
    Dernier message: 08/10/2005, 00h02
  4. Réponses: 12
    Dernier message: 23/06/2005, 16h41
  5. Réponses: 6
    Dernier message: 24/01/2005, 11h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo