I have a list of objects, and I would like to find the first one for which a given method returns true for some input value. This is relatively easy to do in Python:
pattern = next(p for p in pattern_list if p.method(input))
However, in my application it is common that there is no such p
for which p.method(input)
is true, and so this will raise a StopIteration
exception. Is there an idiomatic way to handle this without writing a try/catch block?
In particular, it seems like it would be cleaner to handle that case with something like an if pattern is not None
conditional, so I'm wondering if there's a way to expand my definition of pattern
to provide a None
value when the iterator is empty -- or if there's a more Pythonic way to handle the overall problem!
l = [_ for _ in iterator] # If the list is not empty then the iterator had elements; else it was empty. if l : pass # Use the elements of the list (i.e. from the iterator) else : pass # Iterator was empty, thus list is empty.
The next() function returns the next item in an iterator. You can add a default return value, to return if the iterable has reached to its end.
The __iter__() method returns the iterator object itself. If required, some initialization can be performed. The __next__() method must return the next item in the sequence. On reaching the end, and in subsequent calls, it must raise StopIteration .
The __iter__() function returns an iterator for the given object (array, set, tuple, etc. or custom objects). It creates an object that can be accessed one element at a time using __next__() function, which generally comes in handy when dealing with loops.
next
accepts a default value:
next(...) next(iterator[, default]) Return the next item from the iterator. If default is given and the iterator is exhausted, it is returned instead of raising StopIteration.
and so
>>> print next(i for i in range(10) if i**2 == 9) 3 >>> print next(i for i in range(10) if i**2 == 17) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> print next((i for i in range(10) if i**2 == 17), None) None
Note that you have to wrap the genexp in the extra parentheses for syntactic reasons, otherwise:
>>> print next(i for i in range(10) if i**2 == 17, None) File "<stdin>", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With