Alternative to list comprehension if there will be only one result

You could use a generator expression and next instead. This would be more efficient as well, since an intermediate list is not created and iteration can stop once a match has been found:

actor = next(actor for actor in self.actors if actor.name==actorName)

And as senderle points out, another advantage to this approach is that you can specify a default if no match is found:

actor = next((actor for actor in self.actors if actor.name==actorName), None)

This post has a custom find() function which works quite well, and a commenter there also linked to this method based on generators. Basically, it sounds like there's no single great way to do this — but these solutions aren't bad.


Personally I'd to this in a proper loop.

actor = None
for actor in self.actors:
    if actor.name == actorName:
        break

It's quite a bit longer, but it does have the advantage that it stops looping as soon as a match is found.


If you want to take the first match of potentially many, next(...) is great. But if you expect exactly one, consider writing it defensively:

[actor] = [actor for actor in self.actors if actor.name==actorName]

This always scans to the end, but unlike [0], the destructuring assignment into [actor] throws a ValueError if there are 0 or more than one match. Perhaps even more important then catching bugs, this communicates your assumption to the reader.

If you want a default for 0 matches, but still catch >1 matches:

[actor] = [actor for actor in self.actors if actor.name==actorName] or [default]

P.S. it's also possible to use a generator expression on right side:

[actor] = (actor for actor in self.actors if actor.name==actorName)

which may be a tiny bit more efficient (?). You could also use tuple syntax on the left side — looks more symmetric but the comma is ugly and too easy to miss IMHO:

(actor,) = (actor for actor in self.actors if actor.name==actorName)
actor, = (actor for actor in self.actors if actor.name==actorName)

(anyway list vs tuple syntax on left side is purely cosmetic doesn't affect behavior)