[Python-ideas] __len__() for map()
Steven D'Aprano
steve at pearwood.info
Thu Nov 29 09:43:12 EST 2018
On Thu, Nov 29, 2018 at 02:16:48PM +0100, E. Madison Bray wrote:
> Okay, let's keep it simple:
>
> m = map(str, [1, 2, 3])
> len_of_m = None
> if len(m.iters) == 1 and isinstance(m.iters[0], Sized):
> len_of_m = len(m.iters[0])
>
> You can give me pathological cases where that isn't true, but you
> can't say there's no context in which that wouldn't be virtually
> guaranteed
Yes I can, and they aren't pathological cases. They are ordinary cases
working the way iterators are designed to work.
All you get is a map object. You have no way of knowing how many times
the iterator has been advanced by calling next(). Consequently, there is
no guarantee that len(m.iters[0]) == len(list(m)) except by the merest
accident that the map object hasn't had next() called on it yet.
*This is not pathological behaviour*. This is how iterators are designed
to work.
The ability to partially advance an iterator, pause, then pass it on to
another function to be completed is a huge benefit of the iterator
protocol. I've written code like this on more than one occasion:
# toy example
for x in it:
process(x)
if condition(x):
for y in it:
do_something_else(y)
# Strictly speaking, this isn't needed, since "it" is consumed.
break
If I pass the partially consumed map iterator to your function, it will
use the wrong length and give me back inaccurate results. (Assuming it
actually uses the length as part of the calculated result.)
You might say that your users are not so advanced, or that they're naive
enough not to even know they could do that, but that's a pretty unsafe
assumption as well as being rather insulting to your own users, some of
whom are surely advanced Python coders not just naive dabblers.
Even if only one in a hundred users knows that they can partially
iterate over the map, and only one in a hundred of those actually do so,
you're still making an unsafe assumption that will return inaccurate
results based on an invalid value of len_of_m.
> and consenting adults can decide whether or not that's a
> safe-enough assumption in their own code.
Which consenting adults? How am I, wearing the hat of a Sage user,
supposed to know which of the hundreds of Sage functions make this
"safe-enough" assumption and return inaccurate results as a consequence?
--
Steve
More information about the Python-ideas
mailing list