从列表中删除无值而不删除0值

问题:从列表中删除无值而不删除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会产生很大的不同。

如何从列表中删除无值而不删除0值?

This was my source I started with.

My List

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

When I run this :

L = filter(None, L)

I get this results

[23, 234, 89, 35, 9]

But this is not what I need, what I really need is :

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

Because I’m calculating percentile of the data and the 0 make a lot of difference.

How to remove the None value from a list without removing 0 value?


回答 0

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

Just for fun, here’s how you can adapt filter to do this without using a lambda, (I wouldn’t recommend this code – it’s just for scientific purposes)

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

回答 1

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]

A list comprehension is likely the cleanest way:

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

There is also a functional programming approach but it is more involved:

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

回答 2

对于Python 2.7(请参阅Raymond的答案,对于Python 3等效):

想知道在Python(和其他OO语言)中是否普遍存在“不是None”的东西,以至于在我的Common.py(我使用“ from common import *”导入到每个模块)中,包括了以下几行:

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

然后从列表中删除None元素,只需执行以下操作:

filter(exists, L)

我发现这比相应的列表理解(Raymond以他的Python 2版本显示)更容易阅读。

For Python 2.7 (See Raymond’s answer, for Python 3 equivalent):

Wanting to know whether something “is not None” is so common in python (and other OO languages), that in my Common.py (which I import to each module with “from Common import *”), I include these lines:

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

Then to remove None elements from a list, simply do:

filter(exists, L)

I find this easier to read, than the corresponding list comprehension (which Raymond shows, as his Python 2 version).


回答 3

使用列表理解可以做到以下几点:

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

l的值是:

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

Using list comprehension this can be done as follows:

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

The value of l is:

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

回答 4

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

@jamylak answer is quite nice, however if you don’t want to import a couple of modules just to do this simple task, write your own lambda in-place:

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

回答 5

迭代空间,使用可能是一个问题。在不同情况下,分析可能会显示“更快”和/或“更少的内存”密集型。

# 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优化进行微管理。

Iteration vs Space, usage could be an issue. In different situations profiling may show either to be “faster” and/or “less memory” intensive.

# 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, ...]

The first approach (as also suggested by @jamylak, @Raymond Hettinger, and @Dipto) creates a duplicate list in memory, which could be costly of memory for a large list with few None entries.

The second approach goes through the list once, and then again each time until a None is reached. This could be less memory intensive, and the list will get smaller as it goes. The decrease in list size could have a speed up for lots of None entries in the front, but the worst case would be if lots of None entries were in the back.

The second approach would likely always be slower than the first approach. That does not make it an invalid consideration.

Parallelization and in-place techniques are other approaches, but each have their own complications in Python. Knowing the data and the runtime use-cases, as well profiling the program are where to start for intensive operations or large data.

Choosing either approach will probably not matter in common situations. It becomes more of a preference of notation. In fact, in those uncommon circumstances, numpy (example if L is numpy.array: L = L[L != numpy.array(None) (from here)) or cython may be worthwhile alternatives instead of attempting to micromanage Python optimizations.


回答 6

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

回答 7

如果全部是列表列表,则可以修改@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]"""

<<如果变量不是None,则List中变量的list_indice [0] >>

If it is all a list of lists, you could modify sir @Raymond’s answer

L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) ) for python 2 however

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

<< list_indice[0] for variable in List if variable is not None >>


回答 8

说列表如下

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]

仅过滤无:

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, {}, (), []]

Say the list is like below

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

This will return only those items whose bool(item) is True

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

This is equivalent to

print [item for item in iterator if item]

To just filter None:

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

Equivalent to:

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

To get all the items that evaluate to False

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