1 """Example of a generator: re-implement the built-in range function
2 without actually constructing the list of values.
4 OldStyleRange is coded in the way required to work in a 'for' loop before
5 iterators were introduced into the language; using __getitem__ and __len__ .
8 def handleargs(arglist
):
9 """Take list of arguments and extract/create proper start, stop, and step
10 values and return in a tuple"""
13 return 0, int(arglist
[0]), 1
14 elif len(arglist
) == 2:
15 return int(arglist
[0]), int(arglist
[1]), 1
16 elif len(arglist
) == 3:
18 raise ValueError("step argument must not be zero")
19 return tuple(int(x
) for x
in arglist
)
21 raise TypeError("range() accepts 1-3 arguments, given", len(arglist
))
23 raise TypeError("range() arguments must be numbers or strings "
24 "representing numbers")
27 """Function to implement 'range' as a generator"""
28 start
, stop
, step
= handleargs(a
)
35 """Class implementing a range object.
36 To the user the instances feel like immutable sequences
37 (and you can't concatenate or slice them)
39 Done using the old way (pre-iterators; __len__ and __getitem__) to have an
40 object be used by a 'for' loop.
44 def __init__(self
, *a
):
45 """ Initialize start, stop, and step values along with calculating the
46 nubmer of values (what __len__ will return) in the range"""
47 self
.start
, self
.stop
, self
.step
= handleargs(a
)
48 self
.len = max(0, (self
.stop
- self
.start
) // self
.step
)
51 """implement repr(x) which is also used by print"""
52 return 'range(%r, %r, %r)' % (self
.start
, self
.stop
, self
.step
)
55 """implement len(x)"""
58 def __getitem__(self
, i
):
60 if 0 <= i
<= self
.len:
61 return self
.start
+ self
.step
* i
63 raise IndexError, 'range[i] index out of range'
67 import time
, __builtin__
68 #Just a quick sanity check
69 correct_result
= __builtin__
.range(5, 100, 3)
70 oldrange_result
= list(oldrange(5, 100, 3))
71 genrange_result
= list(genrange(5, 100, 3))
72 if genrange_result
!= correct_result
or oldrange_result
!= correct_result
:
73 raise Exception("error in implementation:\ncorrect = %s"
74 "\nold-style = %s\ngenerator = %s" %
75 (correct_result
, oldrange_result
, genrange_result
))
76 print "Timings for range(1000):"
78 for i
in oldrange(1000):
81 for i
in genrange(1000):
84 for i
in __builtin__
.range(1000):
87 print t2
-t1
, 'sec (old-style class)'
88 print t3
-t2
, 'sec (generator)'
89 print t4
-t3
, 'sec (built-in)'
92 if __name__
== '__main__':