Come creare una lista con una dimensione specifica in Python

Jinku Hu 25 giugno 2020
  1. Preallocazione della memoria per le liste
  2. Preallocazione della memorizzazione per altre strutture di dati sequenziali
Come creare una lista con una dimensione specifica in Python

La preallocazione della memoria per liste o array è uno schema tipico tra i programmatori
quando conoscono il numero di elementi in anticipo.

A differenza di C+++ e Java, in Python, si deve inizializzare tutta la memoria preassegnata con alcuni valori.
Di solito, gli sviluppatori usano valori falsi per questo scopo, come None, '', False, e 0.

Python offre diversi modi per creare una lista di dimensioni fisse, ciascuno con
caratteristiche di prestazione diverse.

Per confrontare le prestazioni dei diversi approcci, useremo lo standard Python
modulo timeit.
Fornisce un modo pratico per misurare i tempi di esecuzione di piccoli pezzi di codice Python.

Preallocazione della memoria per le liste

Il primo e più veloce modo di usare l’operatore *, che ripete una lista di un determinato operatore
numero di volte.

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

Un milione di iterazioni (valore predefinito delle iterazioni in timeit) richiede circa
117 ms.

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

Un altro approccio è quello di utilizzare la funzione integrata range con una comprensione della lista.

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

E’ quasi sei volte più lenta e richiede 612 ms al secondo per milione di iterazioni.

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

Il terzo approccio è quello di usare un semplice cicli for insieme alla list.append().

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

L’utilizzo di loop è il metodo più lento e richiede 842 ms per completare un milione di iterazioni.

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

Preallocazione della memorizzazione per altre strutture di dati sequenziali

Dal momento che si sta preallocando la memorizzazione per una struttura di dati sequenziale, può avere molto senso utilizzare la struttura dei dati incorporata array invece di una lista.

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

Come vediamo qui di seguito, questo approccio è il secondo più veloce dopo [None] * 10.

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

Confrontiamo gli approcci Python puro di cui sopra con il pacchetto NumPy Python per il calcolo scientifico.

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

Il metodo NumPy richiede 589 ms per milione di iterazioni.

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

Tuttavia, il metodo NumPy sarà molto più veloce per liste più massicce.

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

La conclusione è che è meglio attenersi a [None] * 10 per le piccole liste, ma cambiare
al empty() di NumPy quando si tratta di dati sequenziali più massicci.

Autore: 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

Articolo correlato - Python List