[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