Итерация против пространства , использование может быть проблемой. В разных ситуациях профилирование может показывать, что оно «быстрее» и / или «меньше памяти».
# 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, ...]
Первый подход (как и было предложено @jamylak , @Raymond Hettinger и @Dipto ) создает копию списка в памяти, что может быть дорогостоящим для большого списка с несколькоNone записями.
Второй подход проходит через список один раз, а затем снова каждый раз , пока не Noneбудет достигнут. Это может потребовать меньше памяти, и список будет уменьшаться. Уменьшение размера списка может ускорить появление большого количества Noneзаписей в начале, но наихудший случай будет, если многоNone записей появятся сзади.
Параллелизация и методы на месте - это другие подходы, но у каждого есть свои сложности в Python. Знание данных и сценариев использования во время выполнения, а также профилирование программы - это то, с чего начать интенсивную работу или большие данные.
Выбор любого подхода, вероятно, не будет иметь значения в обычных ситуациях. Это становится более предпочтительным обозначением. На самом деле, в этих необычных обстоятельствах numpyили cythonмогут быть полезными альтернативами вместо попыток микроуправления оптимизацией Python.
filterверсия:filter(lambda x: x is not None, L)- Вы могли бы избавиться отlambdaиспользования,partialиoperator.is_notя думаю, но, вероятно, оно того не стоит, так как list-comp намного чище.