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 None
soit 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 None
entré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, numpy
oucython
peuvent être des alternatives valables au lieu de tenter de microgérer les optimisations Python.
filter
version moins élégante :filter(lambda x: x is not None, L)
- Vous pourriez vous débarrasser de l'lambda
utilisationpartial
etoperator.is_not
je pense, mais ça ne vaut probablement pas la peine car la liste-comp est tellement plus propre.