Iteração x Espaço , o uso pode ser um problema. Em diferentes situações, a criação de perfil pode mostrar ser "mais rápida" e / ou "menos memória" intensiva.
# 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, ...]
A primeira abordagem (como também sugerida por @jamylak , @Raymond Hettinger e @Dipto ) cria uma lista duplicada na memória, o que pode custar caro para uma lista grande com poucosNone entradas.
A segunda abordagem percorre a lista uma vez e novamente a cada vez até que a Noneseja atingida. Isso pode consumir menos memória e a lista fica menor à medida que avança. A diminuição no tamanho da lista pode acelerar a Noneentrada de muitas entradas na frente, mas o pior caso seria se muitasNone entradas estivessem na parte de trás.
Paralelização e técnicas no local são outras abordagens, mas cada uma tem suas próprias complicações em Python. Conhecer os casos de uso de dados e tempo de execução, bem como criar um perfil do programa, é o ponto de partida para operações intensivas ou grandes dados.
A escolha de qualquer abordagem provavelmente não será importante em situações comuns. Torna-se mais uma preferência de notação. De fato, nessas circunstâncias incomuns, numpyou cythonpodem ser alternativas que valem a pena, em vez de tentar microgerenciar otimizações de Python.
filterversão menos elegante :filter(lambda x: x is not None, L)- Você pode se livrar dolambdausopartialeoperator.is_noteu acho, mas provavelmente não vale a pena, pois a lista-comp é muito mais limpa.