Comment créer une liste avec une taille spécifique en Python

Jinku Hu 30 janvier 2023
  1. Préallocation de l’espace de stockage pour les listes
  2. Préallocation de la mémoire pour d’autres structures de données séquentielles
Comment créer une liste avec une taille spécifique en Python

La pré-allocation de mémoire pour des listes ou des tableaux est un schéma typique chez les programmeurs
quand ils connaissent le nombre d’éléments à l’avance.

Contrairement à C++ et Java, en Python, vous devez initialiser tout votre stockage pré-alloué avec quelques valeurs.
Habituellement, les développeurs utilisent de fausses valeurs dans ce but, telles que None, False, 0.

Python offre plusieurs façons de créer une liste de taille fixe, chacune avec
différentes caractéristiques de performance.

Pour comparer les performances des différentes approches, nous utiliserons le standard Python
module timeit.
Il fournit un moyen pratique de mesurer le temps d’exécution de petits morceaux de code Python.

Préallocation de l’espace de stockage pour les listes

La première et la plus rapide façon d’utiliser l’opérateur *, qui répète une liste a spécifié
nombre de fois.

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

Un million d’itérations (valeur par défaut des itérations dans timeit) prennent environ
117 ms.

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

Une autre approche consiste à utiliser la fonction intégrée range avec une compréhension de liste.

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

C’est presque six fois plus lent et prend 612 ms par million d’itérations.

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

La troisième approche est d’utiliser une simple boucle for avec la fonction list.append().

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

L’utilisation de boucles est la méthode la plus lente et prend 842 ms pour compléter un million d’itérations.

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

Préallocation de la mémoire pour d’autres structures de données séquentielles

Puisque vous pré-allouez du stockage pour une structure de données séquentielle, il peut être très judicieux d’utiliser la structure de données intégrée array au lieu d’une liste.

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

Comme nous le voyons ci-dessous, cette approche est la deuxième plus rapide après [None] * 10.

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

Comparons les approches Python pures ci-dessus au paquet Python NumPy pour le calcul scientifique.

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

La méthode NumPy prend 589 ms par million d’itérations.

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

Cependant, la méthode NumPy sera beaucoup plus rapide pour des listes plus massives.

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

La conclusion est qu’il est préférable de s’en tenir à [None] * 10 pour les petites listes, mais de passer
à la empty() de NumPy lorsqu’il s’agit de données séquentielles plus massives.

Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - Python List