|
Size: 3082
Comment: if you likethis, please submit a pep.
|
Size: 3377
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 1: | Line 1: |
| Below is a little little range generator, irange, which is compatible with range. More specifically, [i for irange in (*args)] == range(*args)]. This will let us iterator over large spans of numbers without resorting to ["xrange"], which is a lazy list as opposed to a generator. | Below is a little little range generator, irange, which is compatible with range. More specifically, [i for irange in (*args)] == range(*args)]. This will let us iterator over large spans of numbers without resorting to ["xrange"], which is a lazy list as opposed to a generator. |
| Line 3: | Line 3: |
| Would a function of similar semantics likely be accepted into the standard library within itertools? | Would a function of similar semantics likely be accepted into the standard library within itertools? |
| Line 5: | Line 5: |
| The author doesn't have the time/energy to write/push a ["PEP"] for the PythonEnhancementProcess. If you think this generator is a good idea, please submit a ["PEP"]. | ["lwickjr"]: I like the idea. Anyone else? The author doesn't have the time/energy to write/push a ["PEP"] for the PythonEnhancementProcess. If you think this generator is a good idea, please submit a ["PEP"]. ["lwickjr"]: Neither do I. Anyone else? |
| Line 18: | Line 22: |
| Line 23: | Line 27: |
| Line 27: | Line 31: |
| Line 45: | Line 49: |
| [i for i in __irange3(start,stop,step)] produces range(start,stop,step) | [i for i in __irange3(start,stop,step)] produces range(start,stop,step) |
| Line 57: | Line 61: |
| is not created in order to provide the generator. | is not created in order to provide the generator. |
| Line 63: | Line 67: |
| Line 75: | Line 79: |
| Line 85: | Line 89: |
| = Alternate Implementation = Perhaps a simple implementation can be constructed using *count* and *islice* from intertools?. [China Generator Manufacturer | http://www.best-generator.com] [China Neon Sign Manufacturer | http://www.pop-sign-display.com] |
Below is a little little range generator, irange, which is compatible with range. More specifically, [i for irange in (*args)] == range(*args)]. This will let us iterator over large spans of numbers without resorting to ["xrange"], which is a lazy list as opposed to a generator.
Would a function of similar semantics likely be accepted into the standard library within itertools?
["lwickjr"]: I like the idea. Anyone else?
The author doesn't have the time/energy to write/push a ["PEP"] for the PythonEnhancementProcess. If you think this generator is a good idea, please submit a ["PEP"].
["lwickjr"]: Neither do I. Anyone else?
Test Suite
Here is the test:
import unittest
from iter import irange
class TestIter(unittest.TestCase):
def testIrangeValues(self):
testArguments = ( [10],[0],[7,70], [-10], [10,700,17], [10,1000,-3],[10,-99,-7] )
l = lambda *x: list(irange(*x))
for args in testArguments:
list1 = l(*args)
list2 = range(*args)
self.assertEqual(list1,list2)
def testIrangeArguments(self):
self.assertRaises(ValueError,irange,0,99,0) #0 step
#self.assertRaises(irange(1,2,3,4)) #too many arguments
if __name__ == '__main__':
unittest.main()
implementation
"""generator for a range of integers that matches the output
of an iterator over the list range(...)
"""
from itertools import count,takewhile
"""private generator over the unchecked arguments start, stop, step
[i for i in __irange3(start,stop,step)] produces range(start,stop,step)
"""
def __irange3__(start,stop,step):
#the stop condition changes depending on the sign of step
predicate = step > 0 and (lambda x : x < stop) or (lambda x : x > stop)
i = start
while predicate(i):
yield i
i += step
""" generator to produce the same output as an iterator over
range(args). The advantage of this over range() or xrange() is a list
is not created in order to provide the generator.
[i for i in irange(args) ] == [range(args)]
"""
def irange(*args):
if len(args) not in (1,2,3):
raise TypeError, "expected 1,2, or 3 arguments to irange"
#the stop value will be the 1st argument when 1 argument supplied, it
#will the the second argument otherwise. The index is one less than the
#argument
stop = args[(1,0)[len(args) == 1]]
if len(args) == 3:
step = args[2]
#we check the step before we create the generator, for earlier
#error annunciation.
if step == 0:
raise ValueError()
return __irange3__(args[0],stop,step)
#for the cases with no step (1 or two args) its easy to
#use the built in count() generator and filter
predicate = lambda x : x < stop
#set up the arguments to count, depending on whether we have a start
counter_args = len(args) != 1 and [args[0]] or ()
counter = count(*counter_args)
return takewhile(predicate, counter)
Alternate Implementation
Perhaps a simple implementation can be constructed using *count* and *islice* from intertools?. [China Generator Manufacturer | http://www.best-generator.com] [China Neon Sign Manufacturer | http://www.pop-sign-display.com]
