Pythonで理解をリストすることに慣れ始めていますが、私はそれを多少不適切に使用していると思います。リストを使用しているシナリオに数回遭遇しました理解しますが、生成されたリストから最初の(そして唯一の)アイテムをすぐに取得します。次に例を示します。
actor = [actor for actor in self.actors if actor.name==actorName][0]
(self.actorsにはオブジェクトのリストが含まれており、actorNameにある特定の(文字列)名を持つものにアクセスしようとしています。)
私が探しているパラメーターと一致するオブジェクトをリストから引き出しようとしています。この方法は無理ですか?ぶら下がり[0]は少し不安を感じさせます。
代わりにジェネレータ式とnext
を使用できます。中間リストは作成されず、一致が見つかったら反復を停止できるため、これもより効率的です。
actor = next(actor for actor in self.actors if actor.name==actorName)
senderle が指摘するように、このアプローチの別の利点は、一致が見つからない場合にデフォルトを指定できることです。
actor = next((actor for actor in self.actors if actor.name==actorName), None)
潜在的に多数の最初の一致を取りたい場合は、next(...)
が最適です。ただし、1つだけを期待する場合は、防御的に記述することを検討してください。
[actor] = [actor for actor in self.actors if actor.name==actorName]
これは常に最後までスキャンしますが、[0]
とは異なり、[actor]
への構造化は、0または複数の一致がある場合にValueErrorをスローします。おそらくバグをキャッチすることよりもさらに重要であり、これは読者にあなたの仮定を伝えます。
0一致のデフォルトが必要であるが、> 1一致をキャッチする場合:
[actor] = [actor for actor in self.actors if actor.name==actorName] or [default]
追伸右側でジェネレータ式を使用することもできます。
[actor] = (actor for actor in self.actors if actor.name==actorName)
ほんの少し効率的です。あなたは左側でタプル構文を使うことができます—より対称的に見えますが、コンマは醜く、IMHOを見逃すには余りにも簡単です:
(actor,) = [actor for actor in self.actors if actor.name==actorName]
actor, = [actor for actor in self.actors if actor.name==actorName]
この投稿 は、うまく機能するカスタムfind()
関数と、そこにリンクされているコメンター ジェネレータに基づくこのメソッド があります。基本的に、これを行うための優れた方法は1つではないようですが、これらのソリューションは悪くありません。
個人的には、これを適切なループで行います。
actor = None
for actor in self.actors:
if actor.name == actorName:
break
かなり長いですが、一致が見つかるとすぐにループが停止するという利点があります。