[Python-ideas] Map and filter should also convert StopIteration to RuntimeError

Terry Reedy tjreedy at udel.edu
Sat Dec 13 00:12:41 CET 2014

On 12/12/2014 4:21 PM, Chris Angelico wrote:
> On Sat, Dec 13, 2014 at 8:14 AM, Terry Reedy <tjreedy at udel.edu> wrote:
>> I propose that map.__next__ convert StopIteration raised by func to
>> RuntimeError, just as generator.__next__ now does for StopIteration raised
>> by executing a generator function frame.  (And same for filter().)
>> class newmap:
>>      "Simplified version allowing just one input iterable."
>>      def __iter__(self):
>>          return self
>>      def __init__(self, func, iterable):
>>          self.func = func
>>          self.argit = iter(iterable)
>>      def __next__(self):
>>          func = self.func
>>          args = next(self.argit)  # pass on expected StopIteration
>>          if func is None:
>>              return args
>>          else:
>>              try:  # new wrapper
>>                  return func(args)
>>              except StopIteration:
>>                  raise RuntimeError('func raised StopIteration')
> (I'm not sure why you have the "if func is None" check.

Because I initially tried to implement newmap with multiple iterators, I 
looked at the 2.7 itertools.imap equivalent Python code (removed from 
the doc in 3.x) and I forgot that None no longer works.  The check and 
return should be removed.

> Currently map() doesn't accept None as its function.

map.__init__ accepts None, but map.__next__ croaks trying to call it.

> I propose a much MUCH simpler version of map, then:
> def newmap(func, iterable):
>      """Simplified version allowing just one input iterable."""
>      for val in iterable:
>          yield func(val)
> Et voila! Conversion of StopIteration into RuntimeError.

I wrote a class because map is a class with .__next__.  A python 
implementation would better be a generator function, as with examples in 
the itertools doc.

Terry Jan Reedy

More information about the Python-ideas mailing list