Wie man eine Liste mit einer bestimmten Größe in Python erstellt

  1. Vorbelegung von Speicherplatz für Listen
  2. Vorbelegung von Speicherplatz für andere sequentielle Datenstrukturen

Die Vorbelegung von Speicherplatz für Listen oder Arrays ist ein typisches Muster unter Programmierern wenn sie die Anzahl der Elemente im Voraus kennen.

Im Gegensatz zu C++ und Java müssen Sie in Python Ihren gesamten vorbelegten Speicher mit einigen Werten initialisieren. Normalerweise verwenden Entwickler dafür falsche Werte, wie z.B. None, '', False und 0.

Python bietet mehrere Möglichkeiten, eine Liste mit einer festen Größe zu erstellen, jede mit unterschiedliche Leistungsmerkmale.

Um die Leistungen verschiedener Ansätze zu vergleichen, verwenden wir den Python-Standard Modul timeit. Es bietet einen praktischen Weg, um die Laufzeit von kleinen Teilen des Python-Codes zu messen.

Vorbelegung von Speicherplatz für Listen

Der erste und schnellste Weg, den *-Operator zu verwenden, der eine Liste mit einer bestimmten Anzahl von Malen.

>>> [None] * 10
[None, None, None, None, None, None, None, None, None, None]

Eine Million Iterationen (Standardwert der Iterationen in timeit) dauern etwa 117 ms.

>>> timeit("[None] * 10")
0.11655918900214601

Ein anderer Ansatz ist die Verwendung der eingebauten Funktion range mit einem Listenverständnis.

>>> [None for _ in range(10)]
[None, None, None, None, None, None, None, None, None, None]

Sie ist fast sechsmal langsamer und benötigt 612 ms Sekunde pro Million Iterationen.

>>> timeit("[None for _ in range(10)]")
0.6115895550028654

Der dritte Ansatz ist, eine einfache for-Schleife zusammen mit der list.append() zu verwenden.

>>> a = []
>>> for _ in range(10):
...   a.append(None)
...
>>> a
[None, None, None, None, None, None, None, None, None, None]

Die Verwendung von Schleifen ist die langsamste Methode und benötigt 842 ms für eine Million Iterationen.

>>> timeit("for _ in range(10): a.append(None)", setup="a=[]")
0.8420009529945673

Vorbelegung von Speicherplatz für andere sequentielle Datenstrukturen

Da Sie Speicherplatz für eine sequentielle Datenstruktur vorbelegen, kann es sehr sinnvoll sein, die eingebaute Datenstruktur array anstelle einer Liste zu verwenden.

>>> from array import array
>>> array('i',(0,)*10)
array('i', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Wie wir weiter unten sehen, ist dieser Ansatz nach [None] * 10 der zweitschnellste.

>>> timeit("array('i',(0,)*10)", setup="from array import array")
0.4557597979946877

Vergleichen wir die obigen reinen Python-Ansätze mit dem NumPy Python-Paket für wissenschaftliches Rechnen.

>>> from numpy import empty
>>> empty(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

Der NumPy Weg benötigt 589 ms pro Million Iterationen.

>>> timeit("empty(10)", setup="from numpy import empty")
0.5890094790011062

Allerdings wird der NumPy-Weg für umfangreichere Listen viel schneller sein.

>>> timeit("[None]*10000")
16.059584009999526
>>> timeit("empty(10000)", setup="from numpy import empty")
1.1065983309963485

Die Schlussfolgerung ist, dass es am besten ist, sich bei kleinen Listen an [None] * 10 zu halten, aber wechseln zu NumPys empty(), wenn es sich um massivere sequentielle Daten handelt.

Verwandter Artikel - Python List

  • Wie man zwei oder mehrere Listen in Python verkettet
  • Zufällige Auswahl von Elementen aus einer Liste in Python