Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no first(iterable) built-in function in Python?

I'm wondering if there's a reason that there's no first(iterable) in the Python built-in functions, somewhat similar to any(iterable) and all(iterable) (it may be tucked in a stdlib module somewhere, but I don't see it in itertools). first would perform a short-circuit generator evaluation so that unnecessary (and a potentially infinite number of) operations can be avoided; i.e.

def identity(item):     return item  def first(iterable, predicate=identity):     for item in iterable:         if predicate(item):             return item     raise ValueError('No satisfactory value found') 

This way you can express things like:

denominators = (2, 3, 4, 5) lcd = first(i for i in itertools.count(1)     if all(i % denominators == 0 for denominator in denominators)) 

Clearly you can't do list(generator)[0] in that case, since the generator doesn't terminate.

Or if you have a bunch of regexes to match against (useful when they all have the same groupdict interface):

match = first(regex.match(big_text) for regex in regexes) 

You save a lot of unnecessary processing by avoiding list(generator)[0] and short-circuiting on a positive match.

like image 222
cdleary Avatar asked Jul 03 '09 00:07

cdleary


People also ask

Which is not a built-in function in Python?

String() is not an in-built function in python.

What is iterable function in Python?

Definition: An iterable is any Python object capable of returning its members one at a time, permitting it to be iterated over in a for-loop. Familiar examples of iterables include lists, tuples, and strings - any such sequence can be iterated over in a for-loop.

What is the most common iterable in Python?

The two common higher-order functions involving iterables are the map and filter functions.


2 Answers

In Python 2, if you have an iterator, you can just call its next method. Something like:

>>> (5*x for x in xrange(2,4)).next() 10 

In Python 3, you can use the next built-in with an iterator:

>>> next(5*x for x in range(2,4)) 10 
like image 185
liori Avatar answered Oct 23 '22 22:10

liori


There's a Pypi package called “first” that does this:

>>> from first import first >>> first([0, None, False, [], (), 42]) 42 

Here's how you would use to return the first odd number, for example:

>> first([2, 14, 7, 41, 53], key=lambda x: x % 2 == 1) 7 

If you just want to return the first element from the iterator regardless of whether is true or not, do this:

>>> first([0, None, False, [], (), 42], key=lambda x: True) 0 

It's a very small package: it only contains this function, it has no dependencies, and it works on Python 2 and 3. It's a single file, so you don't even have to install it to use it.

In fact, here's almost the entire source code (from version 2.0.1, by Hynek Schlawack, released under the MIT licence):

def first(iterable, default=None, key=None):     if key is None:         for el in iterable:             if el:                 return el     else:         for el in iterable:             if key(el):                 return el     return default 
like image 39
Flimm Avatar answered Oct 23 '22 21:10

Flimm