[Python-ideas] __len__() for map()
Terry Reedy
tjreedy at udel.edu
Tue Dec 11 13:06:47 EST 2018
On 12/1/2018 2:08 PM, Steven D'Aprano wrote:
> This proof of concept wrapper class could have been written any time
> since Python 1.5 or earlier:
>
> class lazymap:
> def __init__(self, function, sequence):
One could now add at the top of the file
from collections.abc import Sequence
and here
if not isinstance(sequence, Sequence):
raise TypeError(f'{sequence} is not a sequence')
> self.function = function
> self.wrapped = sequence
> def __len__(self):
> return len(self.wrapped)
> def __getitem__(self, item):
> return self.function(self.wrapped[item])
For 3.x, I would add
def __iter__: return map(self.function, self.sequence)
but your point that iteration is possible even without, with the old
protocol, is well made.
> It is fully iterable using the sequence protocol, even in Python 3:
>
> py> x = lazymap(str.upper, 'aardvark')
> py> list(x)
> ['A', 'A', 'R', 'D', 'V', 'A', 'R', 'K']
>
>
> Mapped items are computed on demand, not up front. It doesn't make a
> copy of the underlying sequence, it can be iterated over and over again,
> it has a length and random access. And if you want an iterator, you can
> just pass it to the iter() function.
>
> There are probably bells and whistles that can be added (a nicer repr?
> any other sequence methods? a cache?) and I haven't tested it fully.
>
> For backwards compatibilty reasons, we can't just make map() work like
> this, because that's a change in behaviour. There may be tricky corner
> cases I haven't considered, but as a proof of concept I think it shows
> that the basic premise is sound and worth pursuing.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list