What is the difference between range and xrange functions in Python 2.X?

后端 未结 28 2040
深忆病人
深忆病人 2020-11-22 03:14

Apparently xrange is faster but I have no idea why it\'s faster (and no proof besides the anecdotal so far that it is faster) or what besides that is different about

相关标签:
28条回答
  • 2020-11-22 04:08

    When testing range against xrange in a loop (I know I should use timeit, but this was swiftly hacked up from memory using a simple list comprehension example) I found the following:

    import time
    
    for x in range(1, 10):
    
        t = time.time()
        [v*10 for v in range(1, 10000)]
        print "range:  %.4f" % ((time.time()-t)*100)
    
        t = time.time()
        [v*10 for v in xrange(1, 10000)]
        print "xrange: %.4f" % ((time.time()-t)*100)
    

    which gives:

    $python range_tests.py
    range:  0.4273
    xrange: 0.3733
    range:  0.3881
    xrange: 0.3507
    range:  0.3712
    xrange: 0.3565
    range:  0.4031
    xrange: 0.3558
    range:  0.3714
    xrange: 0.3520
    range:  0.3834
    xrange: 0.3546
    range:  0.3717
    xrange: 0.3511
    range:  0.3745
    xrange: 0.3523
    range:  0.3858
    xrange: 0.3997 <- garbage collection?
    

    Or, using xrange in the for loop:

    range:  0.4172
    xrange: 0.3701
    range:  0.3840
    xrange: 0.3547
    range:  0.3830
    xrange: 0.3862 <- garbage collection?
    range:  0.4019
    xrange: 0.3532
    range:  0.3738
    xrange: 0.3726
    range:  0.3762
    xrange: 0.3533
    range:  0.3710
    xrange: 0.3509
    range:  0.3738
    xrange: 0.3512
    range:  0.3703
    xrange: 0.3509
    

    Is my snippet testing properly? Any comments on the slower instance of xrange? Or a better example :-)

    0 讨论(0)
  • 2020-11-22 04:08

    range generates the entire list and returns it. xrange does not -- it generates the numbers in the list on demand.

    0 讨论(0)
  • 2020-11-22 04:08

    On a requirement for scanning/printing of 0-N items , range and xrange works as follows.

    range() - creates a new list in the memory and takes the whole 0 to N items(totally N+1) and prints them. xrange() - creates a iterator instance that scans through the items and keeps only the current encountered item into the memory , hence utilising same amount of memory all the time.

    In case the required element is somewhat at the beginning of the list only then it saves a good amount of time and memory.

    0 讨论(0)
  • 2020-11-22 04:09

    Do spend some time with the Library Reference. The more familiar you are with it, the faster you can find answers to questions like this. Especially important are the first few chapters about builtin objects and types.

    The advantage of the xrange type is that an xrange object will always take the same amount of memory, no matter the size of the range it represents. There are no consistent performance advantages.

    Another way to find quick information about a Python construct is the docstring and the help-function:

    print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
    help(xrange)
    
    0 讨论(0)
  • 2020-11-22 04:09

    What?
    range returns a static list at runtime.
    xrange returns an object (which acts like a generator, although it's certainly not one) from which values are generated as and when required.

    When to use which?

    • Use xrange if you want to generate a list for a gigantic range, say 1 billion, especially when you have a "memory sensitive system" like a cell phone.
    • Use range if you want to iterate over the list several times.

    PS: Python 3.x's range function == Python 2.x's xrange function.

    0 讨论(0)
  • 2020-11-22 04:10

    From the help docs.

    Python 2.7.12

    >>> print range.__doc__
    range(stop) -> list of integers
    range(start, stop[, step]) -> list of integers
    
    Return a list containing an arithmetic progression of integers.
    range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
    When step is given, it specifies the increment (or decrement).
    For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
    These are exactly the valid indices for a list of 4 elements.
    
    >>> print xrange.__doc__
    xrange(stop) -> xrange object
    xrange(start, stop[, step]) -> xrange object
    
    Like range(), but instead of returning a list, returns an object that
    generates the numbers in the range on demand.  For looping, this is 
    slightly faster than range() and more memory efficient.
    

    Python 3.5.2

    >>> print(range.__doc__)
    range(stop) -> range object
    range(start, stop[, step]) -> range object
    
    Return an object that produces a sequence of integers from start (inclusive)
    to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
    start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
    These are exactly the valid indices for a list of 4 elements.
    When step is given, it specifies the increment (or decrement).
    
    >>> print(xrange.__doc__)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'xrange' is not defined
    

    Difference is apparent. In Python 2.x, range returns a list, xrange returns an xrange object which is iterable.

    In Python 3.x, range becomes xrange of Python 2.x, and xrange is removed.

    0 讨论(0)
提交回复
热议问题