1919"""
2020
2121from collections import Sequence , Iterator
22+ from itertools import islice
2223
2324
2425class newrange (Sequence ):
@@ -55,6 +56,18 @@ def __init__(self, *args):
5556 self ._step = step
5657 self ._len = (stop - start ) // step + bool ((stop - start ) % step )
5758
59+ @property
60+ def start (self ):
61+ return self ._start
62+
63+ @property
64+ def stop (self ):
65+ return self ._stop
66+
67+ @property
68+ def step (self ):
69+ return self ._step
70+
5871 def __repr__ (self ):
5972 if self ._step == 1 :
6073 return 'range(%d, %d)' % (self ._start , self ._stop )
@@ -94,12 +107,7 @@ def __contains__(self, value):
94107 return False
95108
96109 def __reversed__ (self ):
97- """Return a range which represents a sequence whose
98- contents are the same as the sequence this range
99- represents, but in the opposite order."""
100- sign = self ._step / abs (self ._step )
101- last = self ._start + ((self ._len - 1 ) * self ._step )
102- return newrange (last , self ._start - sign , - 1 * self ._step )
110+ return iter (self [::- 1 ])
103111
104112 def __getitem__ (self , index ):
105113 """Return the element at position ``index`` in the sequence
@@ -119,40 +127,34 @@ def __getitem_slice(self, slce):
119127 of the sequence represented by this range.
120128 """
121129 start , stop , step = slce .indices (self ._len )
122- return newrange (self [start ], stop + self ._start , step * self ._step )
130+ return newrange (self ._start + self ._step * start ,
131+ self ._start + stop ,
132+ self ._step * step )
123133
124134 def __iter__ (self ):
125135 """Return an iterator which enumerates the elements of the
126136 sequence this range represents."""
127- return rangeiterator (self )
137+ return range_iterator (self )
128138
129139
130- class rangeiterator (Iterator ):
140+ class range_iterator (Iterator ):
131141 """An iterator for a :class:`range`.
132142 """
133-
134- def __init__ (self , rangeobj ):
135- self ._range = rangeobj
136-
137- # Intialize the "last outputted value" to the value
138- # just before the first value; this simplifies next()
139- self ._last = self ._range ._start - self ._range ._step
140- self ._count = 0
143+ def __init__ (self , range_ ):
144+ self ._stepper = islice (_count (range_ .start , range_ .step ), len (range_ ))
141145
142146 def __iter__ (self ):
143- """An iterator is already an iterator, so return ``self``.
144- """
145147 return self
146148
147149 def next (self ):
148- """Return the next element in the sequence represented
149- by the range we are iterating, or raise StopIteration
150- if we have passed the end of the sequence."""
151- self . _last += self . _range . _step
152- self . _count += 1
153- if self . _count > self . _range . _len :
154- raise StopIteration ()
155- return self . _last
150+ return next ( self . _stepper )
151+
152+
153+ # itertools.count in Py 2.6 doesn't accept a step parameter
154+ def _count ( start = 0 , step = 1 ):
155+ while True :
156+ yield start
157+ start += step
156158
157159
158160__all__ = ['newrange' ]
0 commit comments