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 None
seja 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 None
entrada 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, numpy
ou cython
podem ser alternativas que valem a pena, em vez de tentar microgerenciar otimizações de Python.
filter
versão menos elegante :filter(lambda x: x is not None, L)
- Você pode se livrar dolambda
usopartial
eoperator.is_not
eu acho, mas provavelmente não vale a pena, pois a lista-comp é muito mais limpa.