[Python-ideas] __len__() for map()

E. Madison Bray erik.m.bray at gmail.com
Wed Nov 28 09:27:25 EST 2018


On Mon, Nov 26, 2018 at 10:35 PM Kale Kundert <kale at thekunderts.net> wrote:
>
> I just ran into the following behavior, and found it surprising:
>
> >>> len(map(float, [1,2,3]))
> TypeError: object of type 'map' has no len()
>
> I understand that map() could be given an infinite sequence and therefore might not always have a length.  But in this case, it seems like map() should've known that its length was 3.  I also understand that I can just call list() on the whole thing and get a list, but the nice thing about map() is that it doesn't copy data, so it's unfortunate to lose that advantage for no particular reason.
>
> My proposal is to delegate map.__len__() to the underlying iterable.  Similarly, map.__getitem__() could be implemented if the underlying iterable supports item access:

I mostly agree with the existing objections, though I have often found
myself wanting this too, especially now that `map` does not simply
return a list.  This problem alone (along with the same problem for
filter) has had a ridiculously outsized impact on the Python 3 porting
effort for SageMath, and I find it really irritating at times.

As a simple counter-proposal which I believe has fewer issues, I would
really like it if the built-in `map()` and `filter()` at least
provided a Python-level attribute to access the underlying iterables.
This is necessary because if I have a function that used to take, say,
a list as an argument, and it receives a `map` object, I now have to
be able to deal with map()s, and I may have checks I want to perform
on the underlying iterables before, say, I try to iterate over the
`map`.

Exactly what those checks are and whether or not they're useful may be
highly application-specific, which is why say a generic `map.__len__`
is not workable.  However, if I can at least inspect those iterables I
can make my own choices on how to handle the map.

Exposing the underlying iterables to Python also has dangers in that I
could directly call `next()` on them and possibly create some
confusion, but consenting adults and all that...


More information about the Python-ideas mailing list