私のリスト
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値を削除する方法は?
私のリスト
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値を削除する方法は?
回答:
>>> 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]
is_not
存在すら知らなかった!それだけだと思ったのでis_
、楽しみに追加します
is_not
存在し、not_in
存在しません。私は実際にそれnot_in
を魔法の方法に変えるべきだと思います__not_contains__
... しばらく前に尋ねた質問と回答者に加えたコメントを参照してください...それでも解決されたようには感じません。
filterfalse
ユースケースに応じて、単に使用することも、何かを使用することもできると思います
x > y
意味しないことnot x <= y
です。それで、(特に、独自のバイトコードがあるので)意味する必要があります__lt__
__le__
x not in y
not x in y
not in
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]
__ne__
は対照的にpartial
、そのような使用をお勧めしますne
か?
__ne__
?
x != y
内部的に呼び出します。したがって、None以外の値で呼び出されたときにTrueを返すバインドされたメソッドです。例えば、と呼ばれる戻りNotImplemented真の値としてこれを、して返しますFalseを。x.__ne__(y)
None.__ne__
bm = None.__ne__
bm(10)
bm(None)
Python 2.7の場合(レイモンドの回答を参照、Python 3の同等の場合):
「Noneではない」ものがPython(および他のOO言語)で一般的であるか、Common.py(「from Common import *」を使用して各モジュールにインポートする)でそうであるかどうかを知りたいので、次の行を含めます。
def exists(it):
return (it is not None)
次に、リストからNone要素を削除するには、次のようにします。
filter(exists, L)
これは、対応するリスト内包表記(Raymondが彼のPython 2バージョンとして示している)よりも読みやすいと思います。
partial(is_not, None)
、このソリューションでます。私はこれが遅くなると信じています(それはあまり重要ではありませんが)。しかし、pythonモジュールの輸入のカップル、この場合は、カスタム定義された機能を必要とせず、
@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]
[x for x in L if x is not None]
他のコードが私が推奨しないと明示的に述べた単なる追加でした
反復 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, ...]
最初のアプローチは、(ASによっても示唆@jamylak、@Raymondヘッティンガー、及び@Dipto)少数で大規模なリストのために費用がかかる可能性があり、メモリ内の複製リストを作成しますNone
のエントリを。
第二のアプローチは、一度リストを通過した後、再びまでの各時間がNone
到達しています。これはメモリをあまり消費しない可能性があり、リストは小さくなるにつれて小さくなります。リストのサイズを小さくするNone
と、前のエントリの数が増える可能性がありますが、最悪のケースは、None
、背面にエントリがです。
並列化とインプレーステクニックは他のアプローチですが、Pythonではそれぞれ独自の問題があります。データとランタイムのユースケースを理解し、プログラムをプロファイリングすることは、集中的な操作または大きなデータの開始点です。
どちらの方法を選択しても、一般的な状況ではおそらく問題になりません。表記の方が好みになります。実際には、これらの珍しい状況で、numpy
またはcython
代わりにmicromanage Pythonの最適化しようとする価値のある選択肢かもしれません。
L.count(None)
なります。.remove(None)
これによりO(N^2)
、解決しようとしている状況はこのように処理されるべきではなく、データは再構築されるべきですメモリを大量に消費する場合は、代わりにデータベースまたはファイルに保存します。
O(n^2)
リスト全体がの場合のみですNone
。
numpy
このタイプの操作をより最適化された方法で処理できます
numpy
近年使用していますが、それは別のスキルです。もしL
がnumpy.array
Pythonではなくとしてインスタンス化されているlist
、L = L[L != numpy.array(None)]
(stackoverflow.com/a/25255015/3003133)はおそらくどちらよりも優れていますが、その下の処理とメモリの実装の詳細はわかりません。少なくとも、マスクに対してブール値の複製の長さ配列を作成します。このように、アクセス(インデックス)演算子内の比較の構文は、私にとっては初めてです。この議論は私の注目を集めましたdtype=object
。
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]
なしのみをフィルタリングするには:
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, {}, (), []]
filter
バージョン:filter(lambda x: x is not None, L)
-あなたは取り除くことができlambda
使用するpartial
とoperator.is_not
、私は思いますが、リスト-COMPはそんなにきれいであるので、それはおそらく、それだけの価値はありません。