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

Adam Johnson mail.yogi841 at gmail.com
Sat Dec 1 03:58:21 EST 2018


On Sat, 1 Dec 2018 at 01:17, Steven D'Aprano <steve at pearwood.info> wrote:
>
> In principle, we could make this work, by turning the output of map()
> into a view like dict.keys() etc, or a lazy sequence type like range().
> wrapping the underlying sequence. That might be worth exploring. I can't
> think of any obvious problems with a view-like interface, but that
> doesn't mean there aren't any. I've spent like 30 seconds thinking about
> it, so the fact that I can't see any problems with it means little.

Something to consider that, so far, seems to have been overlooked is
that the total length of the resulting map isn't only dependent upon the
iterable, but also the mapped function.

It is a pretty pathological case, but there is no guarantee that the
function is a pure function, free from side effects. If the iterable is
mutable and the mapped function has a reference to it (either from
scoping or the iterable (in)directly containing a reference to itself),
there is nothing to prevent the function modifying the iterable as the
map is evaluated. For example, map can be used as a filter:

it = iter((0, 16, 1, 4, 8, 29, 2, 13, 42))

def filter_odd(x):
    while x % 2 == 0:
        x = next(it)
    return x

tuple(map(filter_odd, it))
# (1, 29, 13)

The above also illustrates the second way the total length of the map
could differ from the length input iterable, even if is immutable. If
StopIteration is raised within the mapped function, map finishes early,
so can be used in a manner similar to takewhile:

def takewhile_lessthan4(x):
    if x < 4:
        return x
    raise StopIteration

tuple(map(takewhile_lessthan4, range(9)))
# (0, 1, 2, 3)

I really don't understand why this is true, under 'normal' usage, map
shouldn't have any reason to silently swallow a StopIteration raised
_within_ the mapped function.


As I opened with, I wouldn't consider using map in either of these ways
to be a good idea, and anyone doing so should probably be persuaded to
find better alternatives, but it might be something to bear in mind.


AJ


More information about the Python-ideas mailing list