Итерация против пространства , использование может быть проблемой. В разных ситуациях профилирование может показывать, что оно «быстрее» и / или «меньше памяти».
# 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 намного чище.