Python-Datenstruktur und interne Implementierung ~ Liste ~

Einführung

Ich benutze Qiita oft, aber dies ist mein erster Beitrag! Freut mich, dich kennenzulernen!

Es gibt viele nützliche Artikel zu Python, aber ich habe den Eindruck, dass es nicht viele Artikel gibt, die sich mit der internen Implementierung von Python befassen. Daher bin ich motiviert, verschiedene Datenstrukturen in Verbindung mit der internen Implementierung erläutern zu können. Dieses Mal werde ich über die Python-Liste schreiben.

Über diesen Artikel

Dies ist ein Artikel über die Funktionsweise von Pythons Liste. Es ist jedoch unmöglich zu schreiben, wie alle Methoden in der Liste funktionieren, also hauptsächlich

――Welche Art von Datenstruktur ist eine Liste? Ist es nicht ein Array? --Was ist die interne Implementierung des Listentyps? --Was ist ein Array mit variabler Länge? Was sind die Regeln zum Ändern der Größe?

Ich habe einen Artikel geschrieben, der solche Fragen lösen kann.

Zielgruppe

Datenstruktur

Mal sehen, welche Art von Datenstruktur der Listentyp von Python ist.

Rezension

Was ist eine Liste?

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

Dies ist der vertraute.

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

Es gibt viele Methoden wie diese (verschiedene).

Verkettete Liste und Array

Es ist eine grundlegende Geschichte. Wenn Sie sie kennen, überspringen Sie sie bitte.

array_vs_linkedlist.png

Das Array ist

--Sichern Sie sich einen durchgehenden Bereich im Speicher und fügen Sie Elemente ein

Verkettete Liste (unidirektional)

Es gibt eine Funktion.

Datenstruktur der Liste

list ist eine Standarddatenstruktur und einer der Sequenztypen. Da es eine Liste heißt, denken einige Leute vielleicht, dass es unter Verwendung einer verketteten Liste implementiert wird, aber Python-Listen werden als Arrays variabler Länge (dynamische Arrays) implementiert. Also ** Python-Liste ist ein Array **. Der Name ist verwirrend. ..

Eine Liste ist ein zusammenhängendes Array mit Verweisen auf andere Objekte. Die Struktur oben in der Liste (PyListObject) hat einen Zeiger und eine Länge auf dieses Array. Betrachten des tatsächlichen cpython-Codes (Include / cpython / listobject.h) (Kommentar weggelassen)

listobject.h


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

Es ist so definiert. Die Liste ist vom Typ "PyListObject" und die Elemente in der Liste sind vom Typ "PyObject" und werden intern dargestellt. (PyObject ist der Basistyp für alle Python-Objekttypen.) "ob_item" ist ein Array von Zeigern auf die Elemente in der Liste, und "zugewiesen" ist die zugewiesene Größe.

Untitled Diagram (2).png

Elemente verschiedener Datentypen können sich in derselben Liste befinden, solange sie "PyObject" sind.

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

Array mit variabler Länge

Ich habe davon gesprochen, dass Pythons Liste ein Array mit variabler Länge ist. Arrays mit variabler Länge ändern die Größe des referenzierten Arrays, wenn Elemente hinzugefügt oder entfernt werden. Die Größe des Arrays wird jedoch nicht jedes Mal geändert. Es fühlt sich gut an zu entscheiden, wann die Größe und ihre Größe erhöht werden soll.

Größe ändern

Der Prozess zum Ändern der Größe des Arrays zum Hinzufügen eines neuen Elements ist wie folgt.

array_expansion.png

Wenn kein freier Speicherplatz vorhanden ist, reservieren Sie einen neuen Speicherplatz, kopieren Sie alle aktuellen Elemente und fügen Sie ein neues Element hinzu.

growth factor Wie viel zu wachsen ist, wenn das Array voll ist, hängt vom ** Wachstumsfaktor ** ab (ungefähr wie oft die Größe des vorhandenen Arrays multipliziert wird). ** Wachstumsfaktor ** hängt von der Sprache ab. (Zum Beispiel ist Python 1.125, C ist 2.)

Wenn der Wachstumsfaktor beispielsweise 2 ist, ist die Größe (Kapazität) wie folgt, wenn Elemente zum Array hinzugefügt werden. DinamicArray.png

Beim Löschen eines Elements ähnelt die Verkleinerung der Vergrößerung.

Berechnungsbetrag

Die Operation zum Erweitern des Arrays kopiert alle Elemente. Wenn also die aktuelle Anzahl von Elementen k ist, beträgt der Berechnungsbetrag O (k).

Betrachten Sie nun, dass der Berechnungsbetrag für list.append (element) O (1) ist. Schlussfolgerung In Anbetracht des Rechenaufwands ist dies O (1).

Wenn beim Hinzufügen von n Elementen zu einem leeren Array der Wachstumsfaktor 2 beträgt, beträgt der Berechnungsaufwand

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

Daher beträgt der Rechenaufwand beim Hinzufügen von n Elementen O (n). Daher beträgt der Berechnungsbetrag für "list.append (element)" O (1).

Implementierung anzeigen

Der Wachstumsfaktor von Python beträgt 1,125, aber lassen Sie uns sehen, wie man ihn konkret wachsen lässt. Operationen, die sich auf die Liste beziehen, sind in Objects / listobject.c beschrieben. Der wichtige Teil der Funktion, dessen Größe geändert werden soll, ist wie folgt.

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;

Es ist schwer, die Maskenberechnung in der zweiten Hälfte zu verstehen, nicht wahr?

Kurz gesagt, multiplizieren Sie die aktuelle Größe mit $ \ frac {9} {8} $ und fügen Sie ein wenig hinzu. Sicherlich beträgt der Wachstumsfaktor 1,125.

Zusammenfassung

Verweise

Recommended Posts

Python-Datenstruktur und interne Implementierung ~ Liste ~
Python interne Struktur
Struktur und Betrieb der Python-Daten (Python-Lernnotiz ③)
[Python-Tutorial] Datenstruktur
Datenstruktur Python Push Pop
Liste der Python-Bibliotheken für Datenwissenschaftler und Dateningenieure
Python-Liste und Tapples und Kommas
Python-Listeneinschlussnotation und Generator
Maxout Beschreibung und Implementierung (Python)
[Python] Kapitel 04-01 Verschiedene Datenstrukturen (Listenerstellung und Elementabruf)
Löse das Spiralbuch (Algorithmus und Datenstruktur) mit Python!
Unterschied zwischen list () und [] in Python
Hashing von Daten in R und Python
Bilderbuch-Datenstrukturalgorithmus Python
[Python] -Liste
Datenpipeline-Aufbau mit Python und Luigi
Warteschlangen- und Python-Implementierungsmodul "deque"
[Python] Kapitel 04-03 Verschiedene Datenstrukturen (mehrdimensionale Liste)
Inklusive Notation von Python (über Liste und Generatorausdruck) [zusätzlich]
[Python] Kapitel 04-04 Verschiedene Datenstrukturen (siehe Liste)
Unterschied zwischen Anhängen und + = in der Python-Liste
PointNet-Theorie und Implementierung (Punktgruppendaten)
[Python] Kapitel 04-02 Verschiedene Datenstrukturen (Listenmanipulation)
Zeichnen Sie Daten einfach in Shell und Python
[Python Iroha] Unterschied zwischen Liste und Tupel
Komprimieren Sie Python-Daten und schreiben Sie in SQLite
Kommunikation verschlüsselter Daten zwischen Python und C #
Machen Sie mit Python einen Entscheidungsbaum von 0 und verstehen Sie ihn (4. Datenstruktur)
Python-Grundlagen: Liste
[Python] Vorsichtsmaßnahmen beim Erfassen von Daten durch Scraping und Einfügen in die Liste
Python-Variablen und Datentypen, die mit Chemoinfomatik gelernt wurden
Datenanalyse Python
Empfangen und Anzeigen von HTML-Formulardaten in Python
[Python] Vertauschen von Zeilen und Spalten mit Numpy-Daten
[Python] Lesen von Daten aus CIFAR-10 und CIFAR-100
[Python] Konvertierungsnotiz zwischen Zeitdaten und numerischen Daten
Liste und Summe
Liste und Numpy
TRIE-Baumimplementierung mit Python und LOUDS
Python> Verständnis / Inklusive Notation> Listenverständnis
Liste des zu verschiebenden und zu merkenden Python-Codes
Versuchen Sie, MLB-Daten auf Mac und Python zu importieren
Erläuterung der Bearbeitungsentfernung und Implementierung in Python
cv2-Funktionen und Datentypen (OpenCV-Python-Bindung)
Python-Listenmanipulation
[Python] Daten lesen
Verwendung für Python-Stapel und -Warteschlangen (Geschwindigkeitsvergleich jeder Datenstruktur)
Verarbeitung von CSV-Daten in voller und halber Breite in Python
Implementierte List und Bool in Python und SQLite3 (persönliche Notiz)
Führen Sie die Sortierimplementierung / Berechnungsmengenanalyse zusammen und experimentieren Sie in Python
[# 2] Mach Minecraft mit Python. ~ Modellzeichnung und Player-Implementierung ~
In der Ehe erlernte logische Symbole (und Implementierungsbeispiele in Python)
Liste des Python-Codes, der bei der Big-Data-Analyse verwendet wird
[Python] So sortieren Sie Diktate in Listen und Instanzen in Listen
Lassen Sie uns zwischen Datenstrukturmanipulation und Logikcode unterscheiden.
Untersuchen Sie den Java- und Python-Datenaustausch mit Apache Arrow
[Python] Kapitel 04-05 Verschiedene Datenstrukturen (Taple-Erstellung und Funktionen)
Sortierte Liste in Python
[Python] Komprimieren und dekomprimieren
Python-Übung 2 - List Inclusion Notation