私は、Beautiful SoupをPythonでHTMLファイルから一部のデータをスクレイピングするために使用しています。BeautifulSoupは、string
およびNoneType
オブジェクトの両方を含むリストを返します。 。すべてのNoneType
オブジェクトを除外したいと思います。
Pythonでは、NoneType
オブジェクトを含むリストは反復可能ではないため、リスト内包表記はこのオプションではありません。具体的には、lis
を含むリストNoneTypes
があり、[x for x in lis (some condition/function)]
のようなことをしようとすると、PythonはエラーをスローしますTypeError: argument of type 'NoneType' is not iterable
。
他の投稿 で見たように、この機能をユーザー定義関数に実装するのは簡単です。これが私の趣味です:
def filterNoneType(lis):
lis2 = []
for l in links: #filter out NoneType
if type(l) == str:
lis2.append(l)
return lis2
ただし、組み込みのPython関数が存在する場合は、この関数を使用したいと考えています。可能な場合は常にコードを単純化したいと思います。Does = PythonリストからNoneType
オブジェクトを削除できる組み込み関数がありますか?
これを行う最もクリーンな方法は次のようになると思います:
#lis = some list with NoneType's
filter(None, lis)
リスト内包表記を使用してこれを行うことができます。
clean = [x for x in lis if x != None]
コメントで指摘したように、基本的に同じバイトコードにコンパイルされる場合でも、is not
を使用することもできます。
clean = [x for x in lis if x is not None]
filter
を使用することもできます(注:これは空の文字列もフィルタリングします。フィルタリング対象をさらに制御したい場合は、None
の代わりに関数を渡すことができます):
clean = filter(None, lis)
より効率的なループ処理が必要な場合は、常に itertools のアプローチがありますが、これらの基本的なアプローチは、ほとんどの場合に有効です。
他の回答が提案されているように、または完全を期すために、リストの理解度:
clean = filter(lambda x: x is not None, lis)
リストが膨大な場合、イテレータのアプローチが優れています。
from itertools import ifilter
clean = ifilter(lambda x: x is not None, lis)
Python3では、_.__ne__
_ dunderメソッド(または、必要に応じて「マジックメソッド」)を使用してこれを実装できます。
_>>> list1 = [0, 'foo', '', 512, None, 0, 'bar']
>>> list(filter(None.__ne__, list1))
[0, 'foo', '', 512, 0, 'bar']
_
これがどのように機能するかです:
None.__ne__(None)
-> False
_None.__ne__(
_ anything _)
_-> NotImplemented
NotImplemented
exeptionは実質的にTrue
です。例:
_>>> bool(None.__ne__('Something'))
True
_
2019年初頭、Pythonには、ゼロや空の文字列などを削除する一般的なピットフォールを回避するNone値をフィルタリングするための組み込み関数がありません
リスト内包表記を使用して、リストからすべてのNoneType
オブジェクトを簡単に削除できます。
lis = [i for i in lis if i is not None]