web-dev-qa-db-ja.com

0値を削除せずにリストからNone値を削除します。

これは私が始めた私の情報源です。

私のリスト

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値を削除せずにリストからNone値を削除する方法は?

207
mongotop
>>> 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]
297
jamylak

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

Python 2.7の場合(Raymondの回答、Python 3と同等のものを参照):

何かが "Noneではない"かどうかを知りたいのは、python(そして他のOO言語)ではとても一般的です。私はこれらの行を含めます:

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

それから、リストからNone要素を削除するには、単純に次のようにします。

filter(exists, L)

対応するリストの内包表記(彼のPython 2バージョンとしてRaymondが示している)よりも、これを読みやすいと思います。

15
ToolmakerSteve

リスト内包表記を使用すると、これは次のように実行できます。

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

Lの値は次のとおりです。

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

@jamylakの答えはなかなかいいですが、この単純な作業を行うためだけに2つのモジュールをインポートしたくない場合は、独自の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]
9
A T

繰り返し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 、および @ Dipto )は、重複するリストをメモリ内に作成します。これは、大きなリストにはコストがかかる可能性があります。 Noneエントリーが少ない.

2番目のアプローチでは、リストを1回ずつ通過し、次にNoneに到達するまで毎回再び通過します。これはメモリ消費量が少なくて済むので、リストは小さくなるにつれて小さくなります。リストサイズを小さくすると、前面のNoneエントリが大量になるとスピードが上がる可能性がありますが、最悪の場合は、Noneエントリが大量にある場合です。

並列化とインプレーステクニックは他のアプローチですが、Pythonにはそれぞれ複雑な問題があります。データとランタイムのユースケースを知ること、そしてプログラムをプロファイリングすることは、集中的な操作や大きなデータのためにどこから始めるべきかということです。

どちらの方法を選択しても、一般的な状況ではおそらく問題になりません。それはより表記法の好みになります。実際、このような珍しい状況では、Pythonの最適化を微量管理するのではなく、numpyまたはcythonが価値のある代替手段になるかもしれません。

5
Kevin

それがすべてリストのリストであれば、@ Raymond's answerのsirを修正することができます。

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

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

<< variableがNoneでなければListのvariableに対するlist_indice [0] >>

2
screaminghard
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))
2
med_abidi

リストが以下のようになっているとします。

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