Iterazione vs spazio , l'utilizzo potrebbe essere un problema. In diverse situazioni la profilazione può mostrare di essere "più veloce" e / o "meno memoria".
# first
>>> L = [0, 23, 234, 89, None, 0, 35, 9, ...]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9, ...]
# second
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> for i in range(L.count(None)): L.remove(None)
[0, 23, 234, 89, 0, 35, 9, ...]
Il primo approccio (come suggerito anche da @jamylak , @Raymond Hettinger e @Dipto ) crea un elenco duplicato in memoria, che potrebbe essere costoso per un elenco di grandi dimensioni con poche None
voci.
Il secondo approccio passa attraverso l'elenco una volta e poi di nuovo ogni volta fino a quando None
viene raggiunto un. Ciò potrebbe richiedere meno memoria e l'elenco diventerà più piccolo man mano che procede. La riduzione delle dimensioni dell'elenco potrebbe accelerare per molte None
voci nella parte anteriore, ma il caso peggiore sarebbe se molte None
voci fossero nella parte posteriore.
Parallelizzazione e tecniche sul posto sono altri approcci, ma ognuno ha le proprie complicazioni in Python. Conoscere i dati e i casi d'uso del runtime, nonché la profilazione del programma sono da dove iniziare per operazioni intensive o dati di grandi dimensioni.
Scegliere uno dei due approcci probabilmente non avrà importanza in situazioni comuni. Diventa più una preferenza di notazione. In effetti, in quelle circostanze insolite, numpy
o cython
potrebbero essere alternative utili invece di tentare di micromanage le ottimizzazioni di Python.
filter
versione meno elegante :filter(lambda x: x is not None, L)
- Potresti sbarazzartilambda
dell'usopartial
eoperator.is_not
penso, ma probabilmente non ne vale la pena poiché l'elenco-comp è molto più pulito.