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
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to