| # Example of a generator: re-implement the built-in range function | 
 | # without actually constructing the list of values.  (It turns out | 
 | # that the built-in function is about 20 times faster -- that's why | 
 | # it's built-in. :-) | 
 |  | 
 |  | 
 | # Wrapper function to emulate the complicated range() arguments | 
 |  | 
 | def range(*a): | 
 | 	if len(a) == 1: | 
 | 		start, stop, step = 0, a[0], 1 | 
 | 	elif len(a) == 2: | 
 | 		start, stop = a | 
 | 		step = 1 | 
 | 	elif len(a) == 3: | 
 | 		start, stop, step = a | 
 | 	else: | 
 | 		raise TypeError, 'range() needs 1-3 arguments' | 
 | 	return Range(start, stop, step) | 
 | 	 | 
 |  | 
 | # Class implementing a range object. | 
 | # To the user the instances feel like immutable sequences | 
 | # (and you can't concatenate or slice them) | 
 |  | 
 | class Range: | 
 |  | 
 | 	# initialization -- should be called only by range() above | 
 | 	def __init__(self, start, stop, step): | 
 | 		if step == 0: | 
 | 			raise ValueError, 'range() called with zero step' | 
 | 		self.start = start | 
 | 		self.stop = stop | 
 | 		self.step = step | 
 | 		self.len = max(0, int((self.stop - self.start) / self.step)) | 
 |  | 
 | 	# implement `x` and is also used by print x | 
 | 	def __repr__(self): | 
 | 		return 'range' + `self.start, self.stop, self.step` | 
 |  | 
 | 	# implement len(x) | 
 | 	def __len__(self): | 
 | 		return self.len | 
 |  | 
 | 	# implement x[i] | 
 | 	def __getitem__(self, i): | 
 | 		if 0 <= i < self.len: | 
 | 			return self.start + self.step * i | 
 | 		else: | 
 | 			raise IndexError, 'range[i] index out of range' | 
 |  | 
 |  | 
 | # Small test program | 
 |  | 
 | def test(): | 
 | 	import time, __builtin__ | 
 | 	print range(10), range(-10, 10), range(0, 10, 2) | 
 | 	for i in range(100, -100, -10): print i, | 
 | 	print | 
 | 	t1 = time.time() | 
 | 	for i in range(1000): | 
 | 		pass | 
 | 	t2 = time.time() | 
 | 	for i in __builtin__.range(1000): | 
 | 		pass | 
 | 	t3 = time.time() | 
 | 	print t2-t1, 'sec (class)' | 
 | 	print t3-t2, 'sec (built-in)' | 
 |  | 
 |  | 
 | test() |