удалить значение None из списка без удаления значения 0

Это был мой источник, с которого я начал.

Мой Список

L = [0, 23, 234, 89, None, 0, 35, 9]

когда я запускаю это :

L = filter(None, L)

Я получаю эти результаты

[23, 234, 89, 35, 9]

но это не то, что мне нужно, что мне действительно нужно:

[0, 23, 234, 89, 0, 35, 9]

потому что я вычисляю процентиль данных, и 0 имеет большое значение.

Как удалить значение None из списка без удаления значения 0?

10 ответов


>>> 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]

просто для удовольствия, вот как вы можете адаптировать filter сделать это без использования lambda (Я не рекомендовал бы этот код - это просто для научных целей)

>>> from operator import is_not
>>> from functools import partial
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(partial(is_not, None), L)
[0, 23, 234, 89, 0, 35, 9]

FWIW, Python 3 упрощает эту проблему:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> list(filter(None.__ne__, L))
[0, 23, 234, 89, 0, 35, 9]

в Python 2 вместо этого вы будете использовать понимание списка:

>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

для Python 2.7 (см. ответ Раймонда, для эквивалента Python 3):

желая знать, является ли что-то "не None" настолько распространенным в python (и других языках OO), что в моем Common.py (который я импортирую в каждый модуль с помощью " from Common import *"), я включаю следующие строки:

def exists(it):
    return (it is not None)

затем, чтобы удалить ни одного элемента из списка, просто сделайте:

filter(exists, L)

Я нахожу это более легким для чтения, чем соответствующее понимание списка (которое Раймонд показывает, как его Версия Python 2).


используя понимание списка это можно сделать следующим образом:

l = [i for i in my_list if i is not None]

значение l:

[0, 23, 234, 89, 0, 35, 9]

@jamylak ответ довольно приятный, однако, если вы не хотите импортировать пару модулей только для выполнения этой простой задачи, напишите свой собственный lambda на месте:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(lambda v: v is not None, L)
[0, 23, 234, 89, 0, 35, 9]

шаг vs пробел использование может быть проблемой. В разных ситуациях профилирование может показать, что оно "быстрее" и/или "меньше памяти".

# 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 и @трипто чего) создает дубликат списка в памяти, что может быть дорогостоящим для большого списка с несколькими None записи.

в второй подход проходит через список один раз, а затем снова каждый раз, пока None достигается. Это может быть менее интенсивной памяти, и список будет становиться меньше, как это происходит. Уменьшение размера списка может ускорить для многих None записи спереди, но в худшем случае будет, если много None записи были в спину.

распараллеливание и методы на месте-это другие подходы, но каждый из них имеет свои собственные осложнения в Python. Знание данные и варианты использования среды выполнения, а также профилирование программы-это то, с чего начать интенсивные операции или большие данные.

выбор любого подхода, вероятно, не будет иметь значения в обычных ситуациях. Это становится больше предпочтением нотации. На самом деле, в этих необычных обстоятельствах,numpy или cython могут быть стоящими альтернативами вместо попытки микроуправления оптимизациями Python.


from operator import is_not
from functools import partial   

filter_null = partial(filter, partial(is_not, None))

# A test case
L = [1, None, 2, None, 3]
L = list(filter_null(L))

скажем, список, как показано ниже

iterator = [None, 1, 2, 0, '', None, False, {}, (), []]

это вернет только те элементы,bool(item) is True

print filter(lambda item: item, iterator)
# [1, 2]

это эквивалентно

print [item for item in iterator if item]

чтобы просто отфильтровать None:

print filter(lambda item: item is not None, iterator)
# [1, 2, 0, '', False, {}, (), []]

эквивалентно:

print [item for item in iterator if item is not None]

чтобы получить все элементы, которые оценивают в False

print filter(lambda item: not item, iterator)
# Will print [None, '', 0, None, False, {}, (), []]

Если это все список списков, вы можете изменить ответ sir @Raymond

L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) ) для python 2 однако

no_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""

>


Это решение использует пока, а не на:

value = None
while value in yourlist:
    yourlist.remove(value)