1)ほとんど英語のスタイル:
in
演算子を使用して存在をテストしてから、remove
メソッドを適用します。
if thing in some_list: some_list.remove(thing)
remove
この方法は、唯一の最初の発生を削除しますthing
、あなたが使用できるすべての出現を除去するために、while
代わりのをif
。
while thing in some_list: some_list.remove(thing)
- 十分に単純で、おそらく私の選択です。小さなリストの場合(ワンライナーには抵抗できません)
このシュートファーストアスク質問最後の態度は、Pythonでは一般的です。オブジェクトが適切かどうかを事前にテストする代わりに、操作を実行して関連する例外をキャッチするだけです。
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
もちろん、上記の例の2番目のexcept節は、疑わしいユーモアの問題であるだけでなく、まったく不必要です(要点は、概念に精通していない人のためにアヒルのタイピングを説明することでした)。
事の複数の発生が予想される場合:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- この特定のユースケースでは少し冗長ですが、Pythonでは非常に慣用的です。
- これは#1よりもパフォーマンスが良い
- PEP 463はtry / exceptの短い構文を提案しましたが、ここでは便利ですが、承認されていません。
ただし、contextlibのsuppress()contextmanager(Python 3.4で導入)を使用すると、上記のコードを次のように簡略化できます。
with suppress(ValueError, AttributeError):
some_list.remove(thing)
繰り返しになりますが、物事の複数の発生が予想される場合:
with suppress(ValueError):
while True:
some_list.remove(thing)
3)機能的なスタイル:
1993年頃、Pythonはなったlambda
、reduce()
、filter()
及びmap()
、の礼儀のLispそれらを逃し、*作業パッチを提出したハッカーを。を使用filter
して、リストから要素を削除できます。
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
あなたのケースに役立つかもしれないショートカットがあります:空のアイテム(実際bool(item) == False
にはNone
、ゼロ、空の文字列、またはその他の空のコレクションなどのアイテム)をフィルターで除外したい場合、最初の引数としてNoneを渡すことができます:
cleaned_list = filter(None, some_list)
- [更新]:Python 2.xでは、
filter(function, iterable)
以前は[item for item in iterable if function(item)]
(または[item for item in iterable if item]
最初の引数がの場合)と同等None
でした。Python 3.xでは、と同等になりました(item for item in iterable if function(item))
。微妙な違いは、リストを返すために使用されるフィルターですが、今はジェネレーター式のように機能します。これは、クリーンなリストを繰り返し処理して破棄するだけの場合は問題ありませんが、リストが本当に必要な場合は、filter()
呼び出しを囲む必要があります。list()
コンストラクタ。
- *これらのLispyフレーバーコンストラクトは、Pythonでは少しエイリアンと見なされます。2005年頃、Guidoはドロップについても話していました
filter
-コンパニオンmap
と一緒にreduce
(それらはまだ消えていませんがreduce
、functoolsモジュールに移動されました。高次関数が好きなら一見の価値があります)。
4)数学的スタイル:
リスト内包表記は、バージョン2.0のPEP 202で導入されて以来、Pythonでのリスト操作に適したスタイルになりました。その背後にある理論的根拠は、リスト内包表記がmap()
、filter()
および/またはネストされたループが現在使用されている状況でリストを作成するためのより簡潔な方法を提供することです。
cleaned_list = [ x for x in some_list if x is not thing ]
ジェネレータ式は、PEP 289によってバージョン2.4で導入されました。ジェネレータ式は、要素を一度に1つずつ反復処理する場合など、完全なリストをメモリに作成する必要がない(またはしたくない)状況に適しています。リストを反復するだけの場合は、ジェネレータ式を遅延評価リスト内包と考えることができます。
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
ノート
- 不等式演算子を使用することができます
!=
代わりにis not
(違いは重要です)
- リストのコピーを意味するメソッドの批評家の場合:一般的な考えに反して、ジェネレータ式はリストの内包よりも常に効率的ではありません-不平を言う前にプロファイリングしてください