Live data from Hacker News

What the heck is an xrange?

late.am

11–20 of 28 posts

Re: What the heck is an xrange?

#11
post #10
post #3

Earlier quoted context omitted.

Great catch. If you want to submit a pull request on github you can get the credit -- github.com/dcrosta/xrange

Thanks for the consideration, but I don't really use github, so you go ahead and take the credit yourself.

OK, thanks. Updated in github and on the blog.

Re: What the heck is an xrange?

#12
post #3
post #2

Nitpicking, but this statement doesn't work with large numbers (which xrange() is supposed to handle correctly): self._len = int(ceil(float(stop - start) / step)) Python supports arbitrary-length integers; you can't just cast those to (fixed-length) floating point numbers without losing precision. It's better to use integer division here, for example: self._len = (stop - start)//step + bool((stop - start)%step) (A va…

Great catch. If you want to submit a pull request on github you can get the credit -- github.com/dcrosta/xrange

A related nitpick: since Python's integers are arbitrary size, technically operations like - and / are not constant time, so your claim of an implementation "with constant-time and constant-space operations" is not true.

However, I understand if that complaint is just too nitpicky for you to want to mention it. Great post btw.

Re: What the heck is an xrange?

#13
post #9
post #5

Earlier quoted context omitted.

Huh -- CPython 2.x doesn't let you create an xrange with values past 2 63-1. CPython 3.x does.

Even 63-bit integers aren't (all) representable in IEEE double floating point values (that Python uses) which have a 53 bits mantissa. For example, int(float(10¹⁸ - 1)) != 10¹⁸ - 1, but xrange(1, 10¹⁸) is perfectly valid (even in Python 2). edit : how do I type two consecutive asterisks on Hacker News? Backslash doesn't seem to work as an escape character.

\\\\

Edit: failure. That's two stymied people :(

Re: What the heck is an xrange?

#15
I had a _very_ similar question during my Google interview. In the course of the day I was tasked with implementing a generator (although answering with `(x for x in foo)` got a smile I did have to build a class) and later in the day was asked how a sequence manager can maintain constant time.

This is an excellent post and every Python hacker should read it. Kudos to the author.

Re: What the heck is an xrange?

#17
post #9

Earlier quoted context omitted.

Even 63-bit integers aren't (all) representable in IEEE double floating point values (that Python uses) which have a 53 bits mantissa. For example, int(float(10¹⁸ - 1)) != 10¹⁸ - 1, but xrange(1, 10¹⁸) is perfectly valid (even in Python 2). edit : how do I type two consecutive asterisks on Hacker News? Backslash doesn't seem to work as an escape character.

\\ \\ Edit: failure. That's two stymied people :(

[deleted]

Re: What the heck is an xrange?

#18
I feel that this kind of combination of lazy evaluation for sequences, together with eager evaluation for imperative code hits a particular sweet spot. Python and Clojure have very nice lazy sequences.

Re: What the heck is an xrange?

#19
Not worth a pull request, but personally I'd replace:

        if len(args) == 1:
            start, stop, step = 0, args[0], 1
        elif len(args) == 2:
            start, stop, step = args[0], args[1], 1
        elif len(args) == 3:
            start, stop, step = args
        else:
            raise TypeError('xrange() requires 1-3 int arguments')
with:

        map = [
                lambda args: (0, args[0], 1),
                lambda args: (args[0], args[1], 1),
                lambda args: args,
              ]
        try:
            start, stop, step = map[len(args)](args)
        except IndexError:
            raise TypeError('xrange() requires 1-3 int arguments')
It's more DRY, and it conveys the intent better.

I would not do such a change to the if step block since its pattern feels noticeably different: "open" checks fit well in a if/else, whereas bunch-of-equalities fit a dispatch map better (plus you can actually modify the map at runtime).

Re: What the heck is an xrange?

#20
post #19

Not worth a pull request, but personally I'd replace: if len(args) == 1: start, stop, step = 0, args[0], 1 elif len(args) == 2: start, stop, step = args[0], args[1], 1 elif len(args) == 3: start, stop, step = args else: raise TypeError('xrange() requires 1-3 int arguments') with: map = [ lambda args: (0, args[0], 1), lambda args: (args[0], args[1], 1), lambda args: args, ] try: start, stop, step = map[len(args)](args…

To me your version is less clearer than the explicit if calls:

* Name 'map' for a variable is a poor choice (as it has same name as the python builtin function map)

* Your version has off by one error, it doesn't give correct results when called with a single element list or if the list has three elements:

  >>>mymap = [
                lambda args: (0, args[0], 1),
                lambda args: (args[0], args[1], 1),
                lambda args: args,
              ]

  >>>args = [5]

  >>>mymap[len(args)](args)
    IndexError 
    Traceback (most recent call last)
    ....
   # This shouldn't be the case, a list with a single
   # element is a valid input

  >>>args = [1,6,1]

  >>>mymap[len(args)](args)
    IndexError   Traceback (most recent call last)
    ...

   # This shouldn't be the case, a list with a three
   # elements is a valid input
Post reply on HN