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 :

dictionnaire ou liste


Sujet :

Python

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur développement de composants
    Inscrit en
    Décembre 2019
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement de composants

    Informations forums :
    Inscription : Décembre 2019
    Messages : 113
    Points : 72
    Points
    72
    Par défaut dictionnaire ou liste
    Bonjour,
    dans le but de raccourcir un code servant à tracer des courbes, j'ai essayé de remplacer des listes par un dictionnaire.
    Après modification du code, je suis surpris de voir que la version du code utilisant des listes "prédéclarées" est plus rapide que la version du code utilisant un dictionnaire (voir code ci dessous avec les print qui affichent clairement une différence dans le temps de traitement)...
    NB: le dictionnaire me parait pourtant intéressant puisqu'il me permet de créer des listes de data dynamiquement.

    ci dessous un exemple de structure de mon code initial:
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    import time
    import random
    debut=time.time()
    liste_courbes=["c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12","c13","c14","c15","c16","c17","c18","c19","c20","c21","c22","c23","c24"]
    liste_1x=[]
    liste_1y=[]
    liste_2x=[]
    liste_2y=[]
    liste_3x=[]
    liste_3y=[]
    liste_4x=[]
    liste_4y=[]
    liste_5x=[]
    liste_5y=[]
     
    for i in range(0,len(liste_courbes),1):
        for j in range(0,50000,1):
            if i == 0:
                x=random.random()
                y=time.time()-debut
                liste_1x.append(x)
                liste_1y.append(y)
            elif i == 1:
                x=random.random()
                y=time.time()-debut
                liste_2x.append(x)
                liste_2y.append(y)
            elif i == 2:
                x=random.random()
                y=time.time()-debut
                liste_3x.append(x)
                liste_3y.append(y)
            elif i == 3:
                x=random.random()
                y=time.time()-debut
                liste_4x.append(x)
                liste_4y.append(y)
            elif i == 4:
                x=random.random()
                y=time.time()-debut
                liste_5x.append(x)
                liste_5y.append(y)
        print(time.time()-debut)
    ci dessous la version de code modifiée... mais finalement plus "lente" que la précédente...
    Pourtant je l'a trouve pratique puisqu'elle est "dynamique" (pas besoin de déclarer un nombre de liste défini)
    NB:dans l'exemple ci dessous j'ai gardé la liste "liste_courbes" mais cette dernière peut aussi se faire "grandir" à l'intérieur du premier "for":
    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
    import time
    import random
     
    debut=time.time()
    dictionnaire={}
    liste_courbes=["c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12","c13","c14","c15","c16","c17","c18","c19","c20","c21","c22","c23","c24"]
    debut=time.time()
    for i in range(0,len(liste_courbes),1):
        dictionnaire[liste_courbes[i]] = []
        for j in range(0,50000,1):
            x=random.random()
            y=time.time()-debut
            dictionnaire[liste_courbes[i]].append(x)
            dictionnaire[liste_courbes[i]].append(y)
        print(time.time()-debut)
    du coup:
    est-ce que j'utilise correctement le dictionnaire?
    est-ce normal de me retrouver avec une utilisation de dictionnaire plus lente qu'avec des listes?
    y a-t-il une solution pour gérer un dictionnaire plus efficacement? est-il possible de lui allouer de la mémoire spécifiquement???
    est-ce que le fait de basculer le traitement/remplissage du dictionnaire dans un thread pourrait améliorer le comportement global?

    merci!

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut


    Variante :

    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
    #! python3
    # coding: utf-8
     
    from time import time
    from random import random
     
    liste_courbes = ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12",
                     "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21", "c22", "c23", "c24"]
     
    debut = time()
     
    datas = {k: [] for k in liste_courbes}
     
    for k, v in datas.items():
        for _ in range(0, 50000):
            datas[k].append([random(), time()])
     
    print(time() - debut) # 0.790565013885498

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Le grand avantage du dictionnaire est dans la rapidité de la recherche de valeurs associées aux clés, et ceci grâce au fait que les clés sont "hashées" => https://fr.wikipedia.org/wiki/Fonction_de_hachage. En contrepartie, les clés doivent être "hashables", et forcément uniques.

    La création du dictionnaire est donc moins rapide qu'une liste puisque sa mise en place nécessite le calcul du "hash" destiné à retrouver plus rapidement son adresse. Il ne faut donc utiliser le dictionnaire que quand on cherche sa rapidité de recherche ultérieure.

    La liste comporte certains avantages par rapport aux dictionnaires, par exemple de pouvoir trier les clés plus facilement, et selon n'importe quel critère (y compris sur les valeurs). Et quand on manipule des "listes de listes", il est intéressant de créer et d'optimiser des fonctions de recherches, filtrages et tris pour rendre la manipulation plus facile et plus fiable.

    Pour accélérer les calculs avec Python, et dans la mesure où ces calculs sont "parallélisables", il vaut mieux utiliser le module "multiprocessing" (ou "concurrent.futures") qui permet d'exploiter les cœurs multiples des CPU modernes (ce que les threads ne font pas). Mais en cas de programme graphique, ce calcul avec multiprocessing peut très bien être lancé par un thread, ce qui permet à ce thread de fournir au graphique les résultats au fur et à mesure qu'ils sont connus, en évitant de geler le graphique.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Membre régulier
    Homme Profil pro
    Ingénieur développement de composants
    Inscrit en
    Décembre 2019
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement de composants

    Informations forums :
    Inscription : Décembre 2019
    Messages : 113
    Points : 72
    Points
    72
    Par défaut
    Bonjour,
    merci à vous deux pour les explications et la variante.
    j'étudie tout ça

  5. #5
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    @clement_74,

    Quel est l'intérêt du code que tu présentes ? Que dois-tu faire concrètement ?

    Par exemple, je comprend pas l'ajout des temps dans tes conteneurs ?

    Que cherches-tu à prouver, démontrer ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 285
    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 285
    Points : 36 773
    Points
    36 773
    Par défaut
    Salut,

    Citation Envoyé par clement_74 Voir le message
    Après modification du code, je suis surpris de voir que la version du code utilisant des listes "prédéclarées" est plus rapide que la version du code utilisant un dictionnaire (voir code ci dessous avec les print qui affichent clairement une différence dans le temps de traitement)...
    Quand on veut comparer des choses aussi dissemblables, on essaie de leur appliquer la même punition. Or, dans votre code utilisant des listes vous créez 10 listes alors que vous en créez 24*2 dans le cas dictionnaires.

    Sûr que les dictionnaires coûtent un peu plus (pas pour tout) mais si vous chargez la barque "contre", vous ne comparez pas grand chose.

    Regardez ce code:
    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
    from time import time
    from random import random
     
    labels = [ 'c%d' % i for i in range(1, 25)]
     
    listes = []
    debut = time()
    for name in labels:
        listes.append([ (random(), time()-debut) for j in range(50000)])
    print(time()-debut)
     
    d = {}
    debut = time()
    for name in labels:
        d[name] = [ (random(), time()-debut) for j in range(50000)]
    print(time()-debut)
    Je sollicite la liste autant que le dictionnaire... et le résultat côté dictionnaire est un peu meilleur. Surprenant, non? Faut-il en conclure que les dictionnaires vont plus vite que les listes? C'est bien plus compliqué que çà!!!

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

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par clement_74 Voir le message
    est-ce que j'utilise correctement le dictionnaire?
    En fait tu utilises surtout mal les listes. En effet, on ne crée pas des variables de style "xxx_1", "xxx_2", "xxx_3" puis un code style if i == 1 alors traiter xxx_1 alors qu'on peut créer une liste "xxx[]" pour traiter simplement xxx[i]. Donc si tu veux faire des tests de benchmarks, commence par écrire un code de base "propre" puis ensuite tu pourras le comparer avec d'autres outils.
    Sinon la réponse de Tyrtamos reste excellente. En effet, pour un dico ce sera plus long de le créer mais ensuite les accès seront plus rapides
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 285
    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 285
    Points : 36 773
    Points
    36 773
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    En effet, pour un dico ce sera plus long de le créer mais ensuite les accès seront plus rapides
    Sauf que j'ai posté un code qui montre justement le contraire.

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

  9. #9
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Sauf qu'avec plus de 100 000 itérations, c'est le contraire qui se passe.

    Ici il n'est ni question de 50 000 ou + itérations, mais nettement moins, ce qui fait que je ne vois pas l'intérêt de faire cela. On devrait plus s'inquiéter de la lisibilité du code à ce stade, surtout quand je vois des c1...cn et des liste_n
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 285
    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 285
    Points : 36 773
    Points
    36 773
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Sauf qu'avec plus de 100 000 itérations, c'est le contraire qui se passe.
    100000 itérations c'est juste changer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            [ (random(), time()-debut) for j in range(50000)]
    mais on créera toujours 24 entrées dans la liste ou le dictionnaire.

    S'il y a des différences (pour ce même boulot), il va falloir se poser des questions sur l'allocation mémoire, la pagination qui fait des ES qui bloquent l'exécution du programme,...

    Donc on va supprimer la création de la liste à 50000/100000 entrées qu'on ajoute à l'ajout (raisonnable) d'un certain nombre d'objets "constants", histoire de réduire les effets de bords... pour constater que si le dictionnaire est un peu moins performant que les listes dans ce genre d'opération, çà reste "acceptable" (et on pourra utiliser un dictionnaire si on en a besoin sans trop se poser de questions).

    Citation Envoyé par fred1599 Voir le message
    On devrait plus s'inquiéter de la lisibilité du code à ce stade, surtout quand je vois des c1...cn et des liste_n
    Le vrai soucis avec le code initial est qu'il compare 5 ajouts dans des listes avec 24 ajouts dans un dictionnaire (faits sans aucune optimisation). Et qu'a partir d'une ânerie pareille, on puisse partir à conjecturer sur le bénéfice que pourrait apporter la parallélisation.

    On se calme, les performances sont un vrai sujet. Pas la peine de s'enflammer sur tout et n'importe quoi: on valide les résultats, on recode décemment, on évalue, on réfléchit,...

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

Discussions similaires

  1. Dictionnaire de liste -> liste de dictionnaire
    Par ju_bicycle dans le forum Général Python
    Réponses: 8
    Dernier message: 01/07/2009, 12h43
  2. Encore ce dictionnaire de listes
    Par Victoria007 dans le forum Général Python
    Réponses: 10
    Dernier message: 15/05/2008, 22h39
  3. Dictionnaire de listes
    Par Victoria007 dans le forum Général Python
    Réponses: 3
    Dernier message: 05/05/2008, 15h35
  4. Dictionnaire et liste de mot
    Par cinette dans le forum Services
    Réponses: 0
    Dernier message: 30/04/2008, 18h47
  5. Problème "for" dans dictionnaire de liste
    Par Sayrus dans le forum Général Python
    Réponses: 3
    Dernier message: 15/02/2006, 16h35

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