Welcome, guest | Sign In | My Account | Store | Cart
import sys
if sys.version_info >= (3,):
    xrange = range

def rev_range(*args):
    """Create a reversed range.

    Equivalent to reversed(list(range(*args))), but without the intermediate
    list.

    This does some simple math on the arguments instead of creating an
    intermediate list and reversing it, thus automating a simple but
    error-prone optimization.
    """
    # Before Python 3.0, range creates a list while xrange is an efficient
    # iterator. From 3.0 onwards, range does what xrange did earlier (and
    # xrange is gone).
    if len(args) == 1:
        # start = 0, stop = args[0], step = 1
        return xrange(args[0]-1, -1, -1)

    # Unpack arguments, setting 'step' to 1 if it is not given.
    start, stop, step = (args + (1,))[:3]

    # The new 'stop' is the first item of the original range plus/minus one,
    # depending on the step's sign. Specifically:
    #   new_stop = start - (1 if step > 0 else -1)
    #
    # The new 'start' is the last item of the original range, which is
    # between one and 'step' less than the original 'stop'. Specifically:
    #
    # * If 'stop' minus 'start' divides by 'step' then the last item of the
    #   original range is 'stop' minus 'step'.
    # * If 'stop' minus 'start' doesn't divide by 'step', then the last item of
    #   the original range is 'stop' minus the remainder of this division.
    #
    # A single expression which accounts for both cases is:
    #   new_start = stop - ((stop-start-1) % step + 1)
    return xrange(stop - ((stop-start-1) % step + 1),
                  start - (1 if step > 0 else -1),
                  -step)

Diff to Previous Revision

--- revision 15 2009-06-10 21:25:50
+++ revision 16 2014-03-29 12:43:26
@@ -1,22 +1,23 @@
+import sys
+if sys.version_info >= (3,):
+    xrange = range
+
 def rev_range(*args):
     """Create a reversed range.
 
-    Equivalent to reversed(list(range(*args))), but more efficient.
+    Equivalent to reversed(list(range(*args))), but without the intermediate
+    list.
 
     This does some simple math on the arguments instead of creating an
     intermediate list and reversing it, thus automating a simple but
-    error-prone optimization often done by programmers.
+    error-prone optimization.
     """
     # Before Python 3.0, range creates a list while xrange is an efficient
     # iterator. From 3.0 onwards, range does what xrange did earlier (and
     # xrange is gone).
-    import sys
-    if sys.version < "3":
-        range = xrange
-
     if len(args) == 1:
         # start = 0, stop = args[0], step = 1
-        return range(args[0]-1, -1, -1)
+        return xrange(args[0]-1, -1, -1)
 
     # Unpack arguments, setting 'step' to 1 if it is not given.
     start, stop, step = (args + (1,))[:3]
@@ -24,7 +25,7 @@
     # The new 'stop' is the first item of the original range plus/minus one,
     # depending on the step's sign. Specifically:
     #   new_stop = start - (1 if step > 0 else -1)
-
+    #
     # The new 'start' is the last item of the original range, which is
     # between one and 'step' less than the original 'stop'. Specifically:
     #
@@ -35,6 +36,6 @@
     #
     # A single expression which accounts for both cases is:
     #   new_start = stop - ((stop-start-1) % step + 1)
-    return range(stop - ((stop-start-1) % step + 1),
-                 start - (1 if step > 0 else -1),
-                 -step)
+    return xrange(stop - ((stop-start-1) % step + 1),
+                  start - (1 if step > 0 else -1),
+                  -step)

History