关于python:从列表中删除无值而不删除0值

remove None value from a list without removing the 0 value

这是我的资料来源。

我的列表

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

当我运行这个时:

1
L = filter(None, L)

我得到这个结果

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

但这不是我需要的,我真正需要的是:

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

因为我在计算数据的百分位数,而0有很大的区别。

如何在不删除0值的情况下从列表中删除"无"值?


1
2
3
>>> 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]

为了好玩,下面介绍如何在不使用lambda的情况下使filter适应这种情况(我不推荐使用此代码-它只是为了科学目的)。

1
2
3
4
5
>>> 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使这个问题变得简单:

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

在Python2中,您将使用列表理解来代替:

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


对于python 2.7(参见Raymond的答案,对于python 3等效物):

想要知道在python(和其他OO语言)中是否有"is not none"这样的东西是如此常见,以至于在common.py(我用"from common import*"导入到每个模块)中,我包括以下行:

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

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

1
filter(exists, L)

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


使用列表理解,可以按如下方式完成:

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

L值为:

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


@Jamylak的回答很好,但是如果您不想只为了完成这个简单的任务而导入几个模块,请在适当的位置编写您自己的lambda

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


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

1
2
3
4
5
6
7
8
9
# 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, ...]

第一种方法(如@jamyak、@raymond hettinger和@dipto所建议的)在内存中创建了一个重复的列表,对于一个只有少量None项的大列表来说,这可能会很昂贵。

第二种方法是对列表进行一次检查,然后每次都进行一次检查,直到到达None。这可能会减少内存占用,而且列表会随着时间的推移而变小。对于前面的很多None条目,列表大小的减少可能会加快速度,但最糟糕的情况是如果后面有很多None条目。

并行化和就地技术是其他方法,但在Python中,它们各自都有各自的复杂性。了解数据和运行时用例,以及分析程序是从何处开始进行密集操作或大型数据。

在通常情况下,选择任何一种方法都可能无关紧要。它更倾向于符号。事实上,在这些不常见的情况下,numpycython可能是值得的替代方案,而不是试图对Python优化进行微观管理。


如果都是列表,您可以修改sir@raymond的答案

埃多克斯1〔10〕但是对于python 2

江户十一〔11〕。

>


1
2
3
4
5
6
7
8
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))


假设列表如下

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

这将只返回其bool(item) is True的项目

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

这相当于

1
print [item for item in iterator if item]

要仅筛选"无",请执行以下操作:

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

相当于:

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

获取所有值为假的项

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


此解决方案使用while而不是用于:

1
2
3
value = None
while value in yourlist:
    yourlist.remove(value)