[Python-ideas] Suggested MapView object (Re: __len__() for map())

Greg Ewing greg.ewing at canterbury.ac.nz
Sat Dec 1 20:07:16 EST 2018

```Steven D'Aprano wrote:
> For backwards compatibilty reasons, we can't just make map() work like
> this, because that's a change in behaviour.

Actually, I think it's possible to get the best of both worlds.
Consider this:

from operator import itemgetter

class MapView:

def __init__(self, func, *args):
self.func = func
self.args = args
self.iterator = None

def __len__(self):
return min(map(len, self.args))

def __getitem__(self, i):
return self.func(*list(map(itemgetter(i), self.args)))

def __iter__(self):
return self

def __next__(self):
if not self.iterator:
self.iterator = map(self.func, *self.args)
return next(self.iterator)

If you give it sequences, it behaves like a sequence:

>>> a = [1, 2, 3, 4, 5]
>>> b = [2, 3, 5]
>>> from math import pow
>>> m = MapView(pow, a, b)
>>> print(list(m))
[1.0, 8.0, 243.0]
>>> print(list(m))
[1.0, 8.0, 243.0]
>>> print(len(m))
3
>>> print(m[1])
8.0

If you give it iterators, it behaves like an iterator:

>>> m = MapView(pow, iter(a), iter(b))
>>> print(next(m))
1.0
>>> print(list(m))
[8.0, 243.0]
>>> print(list(m))
[]
>>> print(len(m))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/greg/foo/mapview/mapview.py", line 14, in __len__
return min(map(len, self.args))
TypeError: object of type 'list_iterator' has no len()

If you use it as an iterator after giving it sequences, it
also behaves like an iterator:

>>> m = MapView(pow, a, b)
>>> print(next(m))
1.0
>>> print(next(m))
8.0

What do people think? Could we drop something like this in as a
replacement for map() without disturbing anything too much?

--
Greg
```

More information about the Python-ideas mailing list