[Python-ideas] Float range class

Guido van Rossum guido at python.org
Sat Jan 10 06:13:17 CET 2015

On Fri, Jan 9, 2015 at 7:29 PM, Andrew Barnert <
abarnert at yahoo.com.dmarc.invalid> wrote:

> On Jan 9, 2015, at 14:36, Guido van Rossum <guido at python.org> wrote:
> > (Although the actual signature of linspace gives me a headache. :-)
> I'm assuming you're not talking about the rested and dtype args (which the
> stdlib wouldn't need), but rather the fact that endpoint changes the
> meaning of num (you effectively generate num+1 points and discard the last,
> instead of generating num points).

All of the above, plus the default to n=50. :-)

Oh, and the name is odd-sounding for someone not from your world.

> I've stumbled over that before, and helped other people with it. But the
> other way around would be confusing just as often. And the confusion
> wouldn't be flagged as quickly as it is in numpy (broadcasting mismatched
> arrays is an error; zipping mismatched sequences is not). And of course it
> would be a gratuitous incompatibility between the stdlib and numpy.
> All of this implies that there's probably some better way to specify
> half-open ranges for linspace that nobody has thought of yet. Hopefully
> someone can think of it now. :)
> Or, failing that, maybe we just don't need half-open linspace in the
> stdlib. You can always do linspace(0, 1, 5+1)[:-1] or, if you want the
> other, linspace(0, 1, 5)[:-1]. Either way, what you're asking for is
> explicit and obvious. And if linspace is a sequence-like view akin to
> range, this doesn't cost anything. And it's even briefer than using the
> endpoint argument (especially since in real life you almost always use it
> as a keyword arg).
> Since Chris seems to have a better intuition than me on how you're usually
> thinking when you need linspace, hopefully he can chime in on whether this
> would be intuitive enough, or if we need an actual solution.

I'm guessing that in terms of implementation you might start with this:

    def  linspace(start, stop, num):
        return [(stop*i + start*(num-i)) / num for i in range(num+1)]

and then refine as follows:

- make it a lazy sequence, with slicing ability, etc.
- numeric tricks to avoid intermediate overflows or numeric instabilities,
plus optimizations
- while still returning exactly the endpoints at the extremes(*)
- and better error checking (num must be an integer > 0)
- and support for start/stop being other numeric types (e.g. complex,
Fraction, Decimal)

Then bikeshed about the module it should live in. At least you can shut
down the bikeshed about the name with "that's what numpy calls it", and
ditto about the argument order. Just don't add any of the other features of
the numpy version. :-)

(*) I was going to give the equally naive definition [start + i*step for i
in range(num+1)] where step is (stop-start)/num, but that would give away
my naiveté even quicker. :-)

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150109/33271f20/attachment.html>

More information about the Python-ideas mailing list