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 :

Comment sont implémentées les listes Python ?


Sujet :

Python

  1. #1
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Comment sont implémentées les listes Python ?
    Bonjour,
    tout est dans la question ou presque. Lors de la "compilation" d'un script Python, quel type C est utilisé pour les listes ?

    Je pose la question pour mieux comprendre les différences de performance entre maListe.pop() et maListe.pop(0).

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

    Une liste Python n'existe pas en C "standard", c'est un objet Python implémenté dans listobject.c.

    En gros, les items de cette liste sont rangés dans un tableau (ob_item).
    Si c'est le dernier élément, il suffit de redimensionner la capacité du tableau.

    Lorsqu'il s'agit d'un autre élément, il faut "avancer" les éléments suivants: c'est cette opération qui va coûter.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Il est conseillé d'utiliser collections.deque plutôt que List si on veut append/pop rapidement aux deux extrémités

  4. #4
    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
    Salut

    A mon avis, le plus simple pour toi (qui a tant envie de comprendre) serait de refaire en C un ersatz de liste Python.

    Et (désolé de contredire wiztricks qui est notre maitre à penser Python), au lieu de passer par un tableau je passerais par une liste chainée, un peu dans ce style...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct s_elem {
        void *pt_data;
        struct s_elem *next;
    } t_elem;
     
    typedef struct {
        t_elem *first;
        size_t nb_elem;
    } t_liste;

    ...ce qui simplifierait assez grandement les opérations append(), del() et pop()...
    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]

  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
    Tout à fait Sve@r, je suis d'accord avec toi, c'est un équivalent d'une deque.

    Mais en fait ce que Wiztrick veut dire est qu'on utilise l'API C avec un tableau (**ob_item) et les dérivés à PyObject. La librairie utilisée est Python.h

    Donc une lib C oui, mais qui sort du standard C habituel, voilà pourquoi la réponse est difficile à donner si tu ne te connais pas un minimum dans l'API C...
    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 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Si rambc a posé cette question, c'est sans doute parce que sa liste est de très grande taille.

    Faire du FIFO sur une structure adaptée pour du LIFO n'est pas "top" et si son cas d'utilisation est FIFO, collections.deque sera mieux.

    Comme il n'a pas indiqué ce qu'il faisait avec, ce mieux côté FIFO ne sera pas forcément bien (dans son contexte).
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Je me suis justement intéressé à ce sujet récemment; je voulais implémenter une structure de donnée similaire au listes Python dans un autre langage et je voulais voir comment elles étaient implémentées.

    Comme l'a dit wiztricks, les listes Python sont implémentées par des tableaux en C dans listobject.c
    Si le tableau devient trop petit, il est redimensionné avec realloc, ce qui peut impliquer la copie complète du tableau. Pour amortir ce coût, une surallocation est faite: chaque fois qu'on doit agrandir le tableau, on alloue environ 12,5% de plus que la taille demandée (pour de grand tableaux; plus que ça quand le tableau est petit):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); /* dans list_resize */
    newsize est la taille demandée; new_allocated correspond à la surallocation. La taille finalement allouée est la somme des deux.

    Si la taille demandée est inférieure à la moitié de la taille allouée, il y a aussi un realloc pour réduire la taille allouée.

    Un pop(0) finira par exécuter le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        if (d < 0) { /* Delete -d items */
            memmove(&item[ihigh+d], &item[ihigh],
                (Py_SIZE(a) - ihigh)*sizeof(PyObject *));
            list_resize(a, Py_SIZE(a) + d);
            ...
    a est un pointeur vers la structure qui représente la liste. item est a->ob_item, le tableau proprement dit. Pour un pop(0), on aura d = -1; ihigh=1. C'est ce memmove qui est coûteux pour un pop(0).

    L'appel à list_resize ci-dessus ne fera la plupart du temps pas de réallocation, sauf si la taille de la liste descend au-dessous de la moitié de la taille actuellement allouée.

    Pour un pop(), le memmove se ferait sur 0 éléments et retournerait donc immédiatement, mais, sans doute pour optimiser, ce code est même court-circuité:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       if (i == Py_SIZE(self) - 1) {
            status = list_resize(self, Py_SIZE(self) - 1);
            assert(status >= 0);
            return v;
        }
    Si l'élément à supprimer est le dernier, il fait juste un appel à list_resize et c'est tout.

  8. #8
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Bonssir,
    désolé pour ce retard mais en ce moment c'est un méga rush... Je regarde vos messages et réponds ce weekend.

  9. #9
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par rambc Voir le message
    Bonssir,
    désolé pour ce retard mais en ce moment c'est un méga rush... Je regarde vos messages et réponds ce weekend.
    Disons plutôt pendant les vacances de Noël...

Discussions similaires

  1. Réponses: 1
    Dernier message: 19/03/2008, 12h56
  2. [c#] Comment sont gérés les noms de DataTable dans un DataSet ?
    Par Seth77 dans le forum Accès aux données
    Réponses: 4
    Dernier message: 10/09/2006, 19h02
  3. comment sont stoquées les données
    Par Biosox dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 12/01/2006, 09h17
  4. Comment sont programmés les plug-ins de jeux
    Par Marneus dans le forum Développement 2D, 3D et Jeux
    Réponses: 2
    Dernier message: 25/11/2005, 18h01
  5. Réponses: 2
    Dernier message: 02/08/2005, 13h53

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