Itération vs espace , l'utilisation pourrait être un problème. Dans différentes situations, le profilage peut s'avérer être "plus rapide" et / ou "moins gourmand en mémoire".
# 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, ...]
La première approche (comme le suggèrent également @jamylak , @Raymond Hettinger et @Dipto ) crée une liste en double en mémoire, ce qui pourrait être coûteux pour une grande liste avec peuNone entrées.
La deuxième approche parcourt la liste une fois, puis à chaque fois jusqu'à ce que a Nonesoit atteint. Cela pourrait être moins gourmand en mémoire et la liste se réduira au fur et à mesure. La diminution de la taille de la liste pourrait avoir une accélération pour de nombreuses Noneentrées à l'avant, mais le pire des cas serait si beaucoup deNone entrées étaient à l'arrière.
La parallélisation et les techniques sur place sont d'autres approches, mais chacune a ses propres complications en Python. Connaître les données et les cas d'utilisation d'exécution, ainsi que le profilage du programme sont où commencer pour des opérations intensives ou des données volumineuses.
Le choix de l'une ou l'autre approche n'aura probablement pas d'importance dans les situations courantes. Cela devient plus une préférence de notation. En fait, dans ces circonstances inhabituelles, numpyoucython peuvent être des alternatives valables au lieu de tenter de microgérer les optimisations Python.
filterversion moins élégante :filter(lambda x: x is not None, L)- Vous pourriez vous débarrasser de l'lambdautilisationpartialetoperator.is_notje pense, mais ça ne vaut probablement pas la peine car la liste-comp est tellement plus propre.