Structure de données Python et implémentation interne ~ Liste ~

introduction

J'utilise beaucoup Qiita, mais c'est mon premier article! Ravi de vous rencontrer!

Il existe de nombreux articles utiles sur Python, mais j'ai l'impression qu'il n'y a pas beaucoup d'articles qui touchent à l'implémentation interne de Python, donc je suis motivé pour pouvoir expliquer différentes structures de données en conjonction avec l'implémentation interne. Cette fois, j'écrirai sur la liste Python.

À propos de cet article

Ceci est un article sur le fonctionnement de la liste de Python. Mais il est impossible d'écrire comment fonctionnent toutes les méthodes de la liste, donc principalement

―― Quel type de structure de données est une liste? N'est-ce pas un tableau?

J'ai écrit un article qui peut résoudre de telles questions.

Public cible

--Les personnes qui ont les questions ci-dessus --Les personnes qui veulent en savoir un peu plus en lisant des livres d'introduction et des tutoriels Python

Structure de données

Voyons quel type de structure de données est le type de liste de Python.

la revue

Qu'est-ce qu'une liste?

>>> x = [1,2,3]
>>> x.append(4)
>>> x
[1, 2, 3, 4]

C'est celui qui est familier.

x.sort()
x.append(element)
x.clear()
x.extend(element)
x.index(element)
x.insert(element)
x.pop()
x.remove(element)
x.reverse()

Il existe de nombreuses méthodes comme celle-ci (diverses).

Liste et tableau concaténés

C'est une histoire basique, donc si vous la connaissez, sautez-la.

array_vs_linkedlist.png

Le tableau est

Liste concaténée (unidirectionnelle)

--Un nœud a un élément et un pointeur vers l'élément suivant --Il faut O (N) pour accéder à l'élément et O (1) pour insérer ou supprimer l'élément.

Il y a une fonctionnalité.

Structure de données de la liste

list est une structure de données standard et est l'un des types de séquence. Puisqu'elle s'appelle une liste, certaines personnes peuvent penser qu'elle est implémentée en utilisant une liste concaténée, mais les listes Python sont implémentées sous forme de tableaux de longueur variable (tableaux dynamiques). Donc ** la liste Python est un tableau **. Le nom est déroutant. ..

Une liste est un tableau contigu avec des références à d'autres objets. La structure en haut de la liste (PyListObject) a un pointeur et une longueur vers ce tableau. En regardant le code cpython réel (ʻInclude / cpython / listobject.h`) (commentaire omis)

listobject.h


typedef struct {
    PyObject_VAR_HEAD
    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

C'est défini comme ça. La liste est de type «PyListObject» et les éléments de la liste sont de type «PyObject» et sont représentés en interne. (PyObject est le type de base pour tous les types d'objets Python.) ʻOb_item est un tableau de pointeurs vers les éléments de la liste, et ʻallocated est la taille allouée.

Untitled Diagram (2).png

Des éléments de différents types de données peuvent être dans la même liste, tant qu'ils sont «PyObject».

x = [1,"a",[1,2,3]]

Tableau de longueur variable

J'ai parlé de la liste de Python comme étant un tableau de longueur variable. Les tableaux de longueur variable redimensionnent le tableau référencé à mesure que des éléments sont ajoutés ou supprimés. Cependant, il ne modifie pas la taille du tableau à chaque fois. Il est bon de décider quand augmenter la taille et sa taille.

Redimensionner

Le processus de redimensionnement du tableau pour ajouter un nouvel élément est le suivant.

array_expansion.png

S'il n'y a pas d'espace libre, réservez un nouvel espace, copiez tous les éléments actuels et ajoutez un nouvel élément.

growth factor La quantité à augmenter lorsque le tableau est plein dépend du ** facteur de croissance ** (environ combien de fois la taille du tableau existant est multipliée). ** facteur de croissance ** dépend de la langue. (Par exemple, Python vaut 1,125, C vaut 2.)

Par exemple, lorsque le facteur de croissance est 2, la taille (capacité) sera la suivante lorsque des éléments sont ajoutés dans l'ordre au tableau. DinamicArray.png

Lors de la suppression d'un élément, la réduction est similaire à l'agrandissement.

Montant du calcul

L'opération pour développer le tableau copie tous les éléments, donc lorsque le nombre actuel d'éléments est k, la quantité de calcul est O (k).

Considérons maintenant que la quantité de calcul pour list.append (element) est O (1). Conclusion Compte tenu de la quantité de calcul, c'est O (1).

Lors de l'ajout de n éléments à un tableau vide dans l'ordre, si le facteur de croissance est 2, la quantité de calcul sera

\begin{align}
O(n+2+2^2+2^3+\cdots+2^{logn}) \\
= O(n+2\times2^{logn})\\
= O(n)
\end{align}

Par conséquent, la quantité de calcul lors de l'ajout de n éléments est O (n). Par conséquent, la quantité de calcul pour «list.append (élément)» est O (1).

Voir l'implémentation

Le facteur de croissance de Python est de 1,125, mais voyons comment le développer concrètement. Les opérations liées à list sont décrites dans ʻObjects / listobject.c`. La partie importante de la fonction à redimensionner est la suivante.

listobject.c


static int
list_resize(PyListObject *self, Py_ssize_t newsize)
{
    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * Add padding to make the allocated size multiple of 4.
     * The growth pattern is:  0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...
     * Note: new_allocated won't overflow because the largest possible value
     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
     */
    new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;
}
    new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;

Il est difficile de comprendre le calcul du masque dans la seconde moitié, n'est-ce pas?

Bref, multipliez la taille actuelle par $ \ frac {9} {8} $ et ajoutez un peu. Le facteur de croissance est certainement de 1,125.

Résumé

Les références

Recommended Posts

Structure de données Python et implémentation interne ~ Liste ~
Structure interne de Python
Structure et fonctionnement des données Python (mémo d'apprentissage Python ③)
[Tutoriel Python] Structure des données
structure de données Python push pop
Liste des bibliothèques Python pour les data scientists et les data ingénieurs
Liste Python et tapples et virgules
Notation et générateur d'inclusion de liste Python
Description et implémentation de Maxout (Python)
[Python] Chapitre 04-01 Différentes structures de données (création de liste et récupération d'éléments)
Résolvez le livre en spirale (algorithme et structure de données) avec python!
Différence entre list () et [] en Python
Hashing de données en R et Python
Algorithme de structure de données de livre d'images Python
[Python] liste
Construction de pipeline de données avec Python et Luigi
Module d'implémentation de file d'attente et Python "deque"
[Python] Chapitre 04-03 Diverses structures de données (liste multidimensionnelle)
Notation inclusive de Python (à propos de l'expression de liste et de générateur) [supplémentaire]
[Python] Chapitre 04-04 Diverses structures de données (voir liste)
Différence entre append et + = dans la liste Python
Théorie et implémentation de PointNet (données de groupe de points)
[Python] Chapitre 04-02 Diverses structures de données (manipulation de liste)
Représentez facilement des données graphiques dans le shell et Python
[Python Iroha] Différence entre List et Tuple
Compressez les données python et écrivez sur sqlite
Communication de données chiffrées entre Python et C #
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (4. Structure des données)
bases de python: liste
[Python] Précautions lors de l'acquisition de données en grattant et en les mettant dans la liste
Variables Python et types de données appris avec la chimio-automatique
Analyse de données python
Recevoir et afficher les données de formulaire HTML en Python
[Python] Permutation des lignes et des colonnes de données Numpy
[Python] Comment lire les données de CIFAR-10 et CIFAR-100
[Python] Mémo de conversion entre les données temporelles et les données numériques
liste et somme
list et numpy
Implémentation de l'arbre TRIE avec Python et LOUDS
Python> Compréhension / Notation inclusive> Compréhension de liste
Liste de code Python à déplacer et à mémoriser
Essayez d'importer des données MLB sur Mac et Python
Explication de la distance d'édition et de l'implémentation en Python
fonctions cv2 et types de données (liaison python OpenCV)
Manipulation de liste Python
[python] Lecture de données
Quoi utiliser pour les piles et les files d'attente Python (comparaison de vitesse de chaque structure de données)
Traitement pleine largeur et demi-largeur des données CSV en Python
Implémentation de List et Bool en Python et SQLite3 (note personnelle)
Fusion de la mise en œuvre du tri / analyse du montant du calcul et de l'expérimentation en Python
[# 2] Créez Minecraft avec Python. ~ Dessin du modèle et implémentation du lecteur ~
Symboles logiques appris dans le mariage (et exemples d'implémentation en Python)
Liste du code Python utilisé dans l'analyse de Big Data
[Python] Comment trier un dict dans une liste et une instance dans une liste
Faisons la distinction entre la manipulation de la structure de données et le code logique.
Étudiez l'échange de données Java et Python avec Apache Arrow
[Python] Chapitre 04-05 Diverses structures de données (création de taple et fonctionnalités)
Liste triée en Python
[python] Compresser et décompresser
Exercice Python 2 - Notation d'inclusion de liste